unsigned int mp_taglist_audio(enum CodecID id) { const struct AVCodecTag *tags[] = {avformat_get_riff_audio_tags(), NULL }; unsigned int tag = av_codec_get_tag(tags, id); if (tag) return tag; return codec_get_tag(mp_wav_tags, id); }
int32_t ContainerFormat :: getOutputCodecTag(ICodec::ID id) { if (!mOutputFormat) return 0; return (int32_t)av_codec_get_tag(mOutputFormat->codec_tag, (enum AVCodecID)id); }
static AVStream* copy_stream(AVFormatContext *context, AVStream *source_stream) { AVStream *output_stream = avformat_new_stream(context, source_stream->codec->codec); AVCodecContext *output_context = output_stream->codec, *source_context = source_stream->codec; output_context->codec_id = source_context->codec_id; output_context->codec_type = source_context->codec_type; if (!output_context->codec_tag) { if (!context->oformat->codec_tag || av_codec_get_id(context->oformat->codec_tag, source_context->codec_tag) == output_context->codec_id || av_codec_get_tag(context->oformat->codec_tag, source_context->codec_id) <=0) { output_context->codec_tag = source_context->codec_tag; } } output_context->bit_rate = source_context->bit_rate; output_context->rc_max_rate = source_context->rc_max_rate; output_context->rc_buffer_size = source_context->rc_buffer_size; output_context->field_order = source_context->field_order; output_context->extradata = av_mallocz(source_context->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!output_context->extradata) { exit(-1); } memcpy(output_context->extradata, source_context->extradata, source_context->extradata_size); output_context->extradata_size = source_context->extradata_size; output_context->time_base = source_context->time_base; switch (output_context->codec_type) { case AVMEDIA_TYPE_AUDIO: output_context->channel_layout = source_context->channel_layout; output_context->sample_rate = source_context->sample_rate; output_context->channels = source_context->channels; output_context->frame_size = source_context->frame_size; output_context->audio_service_type = source_context->audio_service_type; output_context->block_align = source_context->block_align; break; case AVMEDIA_TYPE_VIDEO: output_context->pix_fmt = source_context->pix_fmt; output_context->width = source_context->width; output_context->height = source_context->height; output_context->has_b_frames = source_context->has_b_frames; output_context->sample_aspect_ratio = source_context->sample_aspect_ratio; output_stream->sample_aspect_ratio = output_context->sample_aspect_ratio; default: break; } return output_stream; }
static void output_init() { int i, err; AVCodec *c[2]; char *guess_fp = "a.flv"; // AVStream *st = ; ofc = avformat_alloc_context(); AVOutputFormat *ofmt = av_guess_format(NULL, guess_fp, NULL); ofc->oformat = ofmt; strcpy(ofc->filename, guess_fp); printf("ofc ok\n"); AVStream *ost[2]; ost[0] = avformat_new_stream(ofc, NULL); //ost[0]->codec->codec_id = ist[0]->codec->codec_id; AVCodecContext *codec[2]; codec[0] = ost[0]->codec; avcodec_get_context_defaults3(codec[0], NULL); codec[0]->codec_id = AV_CODEC_ID_H264; codec[0]->codec_type = AVMEDIA_TYPE_VIDEO; codec[0]->time_base.num = 1; codec[0]->time_base.den = 25; codec[0]->width = 720; codec[0]->height = 360; codec[0]->codec_tag = av_codec_get_tag(ofmt->codec_tag, AV_CODEC_ID_H264); printf("ofc->codec codec[0]=%p ofc->st[0]->codec=%p\n", codec[0], ofc->streams[0]->codec); printf("codec[0].tag=%d\n", codec[0]->codec_tag); err = avio_open2(&ofc->pb, output_filename, AVIO_FLAG_WRITE, NULL, NULL); printf("open2=%d\n", err); printf("write header\n"); printf("ofc.nb_streams=%d\n", ofc->nb_streams); printf("ofc.st[0]=%p\n", ofc->streams[0]); printf("ofc.st[0].codec=%p\n", ofc->streams[0]->codec); printf("ofc.oformat=%p\n", ofc->oformat); printf("ofc.oformat.write_header=%p\n", ofc->oformat->write_header); printf("ofc.oformat.name=%s\n", ofc->oformat->name); printf("ofc.pb=%p\n", ofc->pb); printf("ofc.st[0].avg_frame_rate={%d,%d}\n", ofc->streams[0]->avg_frame_rate.num, ofc->streams[0]->avg_frame_rate.den ); printf("ofc.st[0].codec.timebase={%d,%d}\n", ofc->streams[0]->codec->time_base.num, ofc->streams[0]->codec->time_base.den ); printf("ofc.priv=%p\n", ofc->priv_data); //err = ofc->oformat->write_header(ofc); err = avformat_write_header(ofc, NULL); printf("write_header=%d\n", err); avio_flush(ofc->pb); }
uint32_t mp_codec_id2tag(enum CodecID codec_id, uint32_t old_tag, int audio) { const struct AVCodecTag *taglists[3]; // For some formats (like PCM) always trust CODEC_ID_* more than codec_tag uint32_t tag = av_codec_get_tag(mp_codecid_override_taglists, codec_id); if (tag) return tag; // mp4a tag is used for all mp4 files no matter what they actually contain // mp4v is sometimes also used for files containing e.g. mjpeg if (audio && old_tag != MKTAG('m', 'p', '4', 'a') || !audio && old_tag != MKTAG('m', 'p', '4', 'v')) tag = old_tag; if (tag) return tag; get_taglists(taglists, audio); return av_codec_get_tag(taglists, codec_id); }
static void add_codec_to_list(const struct ff_format_desc *format_desc, struct ff_codec_desc **first, struct ff_codec_desc **current, enum AVCodecID id, const AVCodec *codec) { if (codec == NULL) codec = avcodec_find_encoder(id); // No codec, or invalid id if (codec == NULL) return; // Not an encoding codec if (!av_codec_is_encoder(codec)) return; // Format doesn't support this codec unsigned int tag = av_codec_get_tag(format_desc->codec_tags, codec->id); if (tag == 0) return; struct ff_codec_desc *d = av_mallocz(sizeof(struct ff_codec_desc)); d->name = codec->name; d->long_name = codec->long_name; d->id = codec->id; AVCodec *base_codec = avcodec_find_encoder(codec->id); if (strcmp(base_codec->name, codec->name) != 0) { d->alias = true; d->base_name = base_codec->name; } switch (codec->type) { case AVMEDIA_TYPE_AUDIO: d->type = FF_CODEC_AUDIO; break; case AVMEDIA_TYPE_VIDEO: d->type = FF_CODEC_VIDEO; break; default: d->type = FF_CODEC_UNKNOWN; } if (*current != NULL) (*current)->next = d; else *first = d; *current = d; }
static int init_muxer(AVFormatContext *s, AVDictionary **options) { int ret = 0, i; AVStream *st; AVDictionary *tmp = NULL; AVCodecContext *codec = NULL; AVOutputFormat *of = s->oformat; const AVCodecDescriptor *desc; if (options) av_dict_copy(&tmp, *options, 0); if ((ret = av_opt_set_dict(s, &tmp)) < 0) goto fail; #if FF_API_LAVF_BITEXACT if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) s->flags |= AVFMT_FLAG_BITEXACT; #endif // some sanity checks if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) { av_log(s, AV_LOG_ERROR, "no streams\n"); ret = AVERROR(EINVAL); goto fail; } for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; codec = st->codec; #if FF_API_LAVF_CODEC_TB FF_DISABLE_DEPRECATION_WARNINGS if (!st->time_base.num && codec->time_base.num) { av_log(s, AV_LOG_WARNING, "Using AVStream.codec.time_base as a " "timebase hint to the muxer is deprecated. Set " "AVStream.time_base instead.\n"); avpriv_set_pts_info(st, 64, codec->time_base.num, codec->time_base.den); } FF_ENABLE_DEPRECATION_WARNINGS #endif if (!st->time_base.num) { /* fall back on the default timebase values */ if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->sample_rate) avpriv_set_pts_info(st, 64, 1, codec->sample_rate); else avpriv_set_pts_info(st, 33, 1, 90000); } switch (codec->codec_type) { case AVMEDIA_TYPE_AUDIO: if (codec->sample_rate <= 0) { av_log(s, AV_LOG_ERROR, "sample rate not set\n"); ret = AVERROR(EINVAL); goto fail; } if (!codec->block_align) codec->block_align = codec->channels * av_get_bits_per_sample(codec->codec_id) >> 3; break; case AVMEDIA_TYPE_VIDEO: if ((codec->width <= 0 || codec->height <= 0) && !(of->flags & AVFMT_NODIMENSIONS)) { av_log(s, AV_LOG_ERROR, "dimensions not set\n"); ret = AVERROR(EINVAL); goto fail; } if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)) { if (st->sample_aspect_ratio.num != 0 && st->sample_aspect_ratio.den != 0 && codec->sample_aspect_ratio.den != 0 && codec->sample_aspect_ratio.den != 0) { av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer " "(%d/%d) and encoder layer (%d/%d)\n", st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den); ret = AVERROR(EINVAL); goto fail; } } break; } desc = avcodec_descriptor_get(codec->codec_id); if (desc && desc->props & AV_CODEC_PROP_REORDER) st->internal->reorder = 1; if (of->codec_tag) { if (codec->codec_tag && codec->codec_id == AV_CODEC_ID_RAWVIDEO && !av_codec_get_tag(of->codec_tag, codec->codec_id) && !validate_codec_tag(s, st)) { // the current rawvideo encoding system ends up setting // the wrong codec_tag for avi, we override it here codec->codec_tag = 0; } if (codec->codec_tag) { if (!validate_codec_tag(s, st)) { char tagbuf[32]; av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag); av_log(s, AV_LOG_ERROR, "Tag %s/0x%08x incompatible with output codec id '%d'\n", tagbuf, codec->codec_tag, codec->codec_id); ret = AVERROR_INVALIDDATA; goto fail; } } else codec->codec_tag = av_codec_get_tag(of->codec_tag, codec->codec_id); } if (of->flags & AVFMT_GLOBALHEADER && !(codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers " "but container format requires global headers\n", i); if (codec->codec_type != AVMEDIA_TYPE_ATTACHMENT) s->internal->nb_interleaved_streams++; } if (!s->priv_data && of->priv_data_size > 0) { s->priv_data = av_mallocz(of->priv_data_size); if (!s->priv_data) { ret = AVERROR(ENOMEM); goto fail; } if (of->priv_class) { *(const AVClass **)s->priv_data = of->priv_class; av_opt_set_defaults(s->priv_data); if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) goto fail; } } /* set muxer identification string */ if (!(s->flags & AVFMT_FLAG_BITEXACT)) { av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0); } if (options) { av_dict_free(options); *options = tmp; } return 0; fail: av_dict_free(&tmp); return ret; }
int mpae_init_lavc(audio_encoder_t *encoder) { encoder->params.samples_per_frame = encoder->params.sample_rate; encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8; if(!lavc_param_acodec) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); return 0; } init_avcodec(); lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec); if (!lavc_acodec) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec); return 0; } if(lavc_param_atag == 0) { lavc_param_atag = av_codec_get_tag(mp_wav_taglists, lavc_acodec->id); if(!lavc_param_atag) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); return 0; } } lavc_actx = avcodec_alloc_context(); if(lavc_actx == NULL) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); return 0; } lavc_actx->codec_type = CODEC_TYPE_AUDIO; lavc_actx->codec_id = lavc_acodec->id; // put sample parameters lavc_actx->channels = encoder->params.channels; lavc_actx->sample_rate = encoder->params.sample_rate; lavc_actx->time_base.num = 1; lavc_actx->time_base.den = encoder->params.sample_rate; if(lavc_param_abitrate<1000) lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate * 1000; else lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate; if(lavc_param_audio_avopt){ if(parse_avopts(lavc_actx, lavc_param_audio_avopt) < 0){ mp_msg(MSGT_MENCODER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_param_audio_avopt); return 0; } } /* * Special case for adpcm_ima_wav. * The bitrate is only dependent on samplerate. * We have to known frame_size and block_align in advance, * so I just copied the code from libavcodec/adpcm.c * * However, ms adpcm_ima_wav uses a block_align of 2048, * lavc defaults to 1024 */ if(lavc_param_atag == 0x11) { int blkalign = 2048; int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; } if((lavc_param_audio_global_header&1) /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; } if(lavc_param_audio_global_header&2){ lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; } if(avcodec_open(lavc_actx, lavc_acodec) < 0) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); return 0; } if(lavc_param_atag == 0x11) { lavc_actx->block_align = 2048; lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; } encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels; while (encoder->decode_buffer_size < 1024) encoder->decode_buffer_size *= 2; encoder->bind = bind_lavc; encoder->get_frame_size = get_frame_size; encoder->encode = encode_lavc; encoder->close = close_lavc; return 1; }
STDMETHODIMP CLAVFStreamInfo::CreateAudioMediaType(AVFormatContext *avctx, AVStream *avstream) { // Make sure DTS Express has valid settings if (avstream->codec->codec_id == AV_CODEC_ID_DTS && avstream->codec->codec_tag == 0xA2) { avstream->codec->channels = avstream->codec->channels ? avstream->codec->channels : 2; avstream->codec->sample_rate = avstream->codec->sample_rate ? avstream->codec->sample_rate : 48000; } if (avstream->codec->codec_tag == 0) { avstream->codec->codec_tag = av_codec_get_tag(mp_wav_taglists, avstream->codec->codec_id); } if (avstream->codec->channels == 0 || avstream->codec->sample_rate == 0 || (is_mpeg_audio(avstream->codec->codec_id) && avstream->codec->frame_size == 0)) { if (avstream->codec->codec_id == AV_CODEC_ID_AAC && avstream->codec->bit_rate) { if (!avstream->codec->channels) avstream->codec->channels = 2; if (!avstream->codec->sample_rate) avstream->codec->sample_rate = 48000; } else return E_FAIL; } CMediaType mtype = g_AudioHelper.initAudioType(avstream->codec->codec_id, avstream->codec->codec_tag, m_containerFormat); if(mtype.formattype == FORMAT_WaveFormatEx) { // Special Logic for the MPEG1 Audio Formats (MP1, MP2) if(mtype.subtype == MEDIASUBTYPE_MPEG1AudioPayload) { mtype.pbFormat = (BYTE *)g_AudioHelper.CreateMP1WVFMT(avstream, &mtype.cbFormat); } else if (mtype.subtype == MEDIASUBTYPE_BD_LPCM_AUDIO) { mtype.pbFormat = (BYTE *)g_AudioHelper.CreateWVFMTEX_LPCM(avstream, &mtype.cbFormat); mtypes.push_back(mtype); mtype.subtype = MEDIASUBTYPE_HDMV_LPCM_AUDIO; } else if ((mtype.subtype == MEDIASUBTYPE_PCM || mtype.subtype == MEDIASUBTYPE_IEEE_FLOAT) && avstream->codec->codec_tag != WAVE_FORMAT_EXTENSIBLE) { // Create raw PCM media type mtype.pbFormat = (BYTE *)g_AudioHelper.CreateWFMTEX_RAW_PCM(avstream, &mtype.cbFormat, mtype.subtype, &mtype.lSampleSize); } else { WAVEFORMATEX *wvfmt = g_AudioHelper.CreateWVFMTEX(avstream, &mtype.cbFormat); if (avstream->codec->codec_tag == WAVE_FORMAT_EXTENSIBLE && avstream->codec->extradata_size >= 22) { // The WAVEFORMATEXTENSIBLE GUID is not recognized by the audio renderers // Set the actual subtype as GUID WAVEFORMATEXTENSIBLE *wvfmtex = (WAVEFORMATEXTENSIBLE *)wvfmt; mtype.subtype = wvfmtex->SubFormat; } mtype.pbFormat = (BYTE *)wvfmt; if (avstream->codec->codec_id == AV_CODEC_ID_FLAC) { // These are required to block accidental connection to ReClock wvfmt->nAvgBytesPerSec = (wvfmt->nSamplesPerSec * wvfmt->nChannels * wvfmt->wBitsPerSample) >> 3; wvfmt->nBlockAlign = 1; mtype.subtype = MEDIASUBTYPE_FLAC_FRAMED; mtypes.push_back(mtype); mtype.subtype = MEDIASUBTYPE_FLAC; } else if (avstream->codec->codec_id == AV_CODEC_ID_EAC3) { mtypes.push_back(mtype); mtype.subtype = MEDIASUBTYPE_DOLBY_DDPLUS_ARCSOFT; } else if (avstream->codec->codec_id == AV_CODEC_ID_DTS) { wvfmt->wFormatTag = WAVE_FORMAT_DTS2; if (avstream->codec->profile >= FF_PROFILE_DTS_HD_HRA) { mtype.subtype = MEDIASUBTYPE_DTS_HD; mtypes.push_back(mtype); } mtype.subtype = MEDIASUBTYPE_WAVE_DTS; } else if (avstream->codec->codec_id == AV_CODEC_ID_TRUEHD) { //wvfmt->wFormatTag = (WORD)WAVE_FORMAT_TRUEHD; mtypes.push_back(mtype); mtype.subtype = MEDIASUBTYPE_DOLBY_TRUEHD_ARCSOFT; } else if (avstream->codec->codec_id == AV_CODEC_ID_AAC) { wvfmt->wFormatTag = (WORD)MEDIASUBTYPE_AAC_ADTS.Data1; CMediaType adtsMtype = mtype; adtsMtype.subtype = MEDIASUBTYPE_AAC_ADTS; // Clear artificially generated extradata so we don't confuse LAV Audio if (m_containerFormat == "mpeg" || m_containerFormat == "mpegts") { adtsMtype.cbFormat = sizeof(WAVEFORMATEX); ((WAVEFORMATEX *)adtsMtype.pbFormat)->cbSize = 0; } mtypes.push_back(adtsMtype); mtype.subtype = MEDIASUBTYPE_AAC; wvfmt->wFormatTag = (WORD)mtype.subtype.Data1; } else if (avstream->codec->codec_id == AV_CODEC_ID_AAC_LATM) { mtypes.push_back(mtype); mtype.subtype = MEDIASUBTYPE_MPEG_LOAS; wvfmt->wFormatTag = (WORD)mtype.subtype.Data1; } }
bool ExportFFmpeg::InitCodecs(AudacityProject *project) { AVCodec *codec = NULL; AVDictionary *options = NULL; // Configure the audio stream's codec context. mEncAudioCodecCtx = mEncAudioStream->codec; mEncAudioCodecCtx->codec_id = ExportFFmpegOptions::fmts[mSubFormat].codecid; mEncAudioCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO; mEncAudioCodecCtx->codec_tag = av_codec_get_tag((const AVCodecTag **)mEncFormatCtx->oformat->codec_tag,mEncAudioCodecCtx->codec_id); mSampleRate = (int)project->GetRate(); mEncAudioCodecCtx->global_quality = -99999; //quality mode is off by default; // Each export type has its own settings switch (mSubFormat) { case FMT_M4A: mEncAudioCodecCtx->bit_rate = 98000; mEncAudioCodecCtx->bit_rate *= mChannels; mEncAudioCodecCtx->profile = FF_PROFILE_AAC_LOW; mEncAudioCodecCtx->cutoff = 0; mEncAudioCodecCtx->global_quality = gPrefs->Read(wxT("/FileFormats/AACQuality"),-99999); if (!CheckSampleRate(mSampleRate, ExportFFmpegOptions::iAACSampleRates[0], ExportFFmpegOptions::iAACSampleRates[11], &ExportFFmpegOptions::iAACSampleRates[0])) { mSampleRate = AskResample(mEncAudioCodecCtx->bit_rate,mSampleRate, ExportFFmpegOptions::iAACSampleRates[0], ExportFFmpegOptions::iAACSampleRates[11], &ExportFFmpegOptions::iAACSampleRates[0]); } break; case FMT_AC3: mEncAudioCodecCtx->bit_rate = gPrefs->Read(wxT("/FileFormats/AC3BitRate"), 192000); if (!CheckSampleRate(mSampleRate,ExportFFmpegAC3Options::iAC3SampleRates[0], ExportFFmpegAC3Options::iAC3SampleRates[2], &ExportFFmpegAC3Options::iAC3SampleRates[0])) mSampleRate = AskResample(mEncAudioCodecCtx->bit_rate,mSampleRate, ExportFFmpegAC3Options::iAC3SampleRates[0], ExportFFmpegAC3Options::iAC3SampleRates[2], &ExportFFmpegAC3Options::iAC3SampleRates[0]); break; case FMT_AMRNB: mSampleRate = 8000; mEncAudioCodecCtx->bit_rate = gPrefs->Read(wxT("/FileFormats/AMRNBBitRate"), 12200); break; case FMT_WMA2: mEncAudioCodecCtx->bit_rate = gPrefs->Read(wxT("/FileFormats/WMABitRate"), 198000); if (!CheckSampleRate(mSampleRate,ExportFFmpegWMAOptions::iWMASampleRates[0], ExportFFmpegWMAOptions::iWMASampleRates[4], &ExportFFmpegWMAOptions::iWMASampleRates[0])) mSampleRate = AskResample(mEncAudioCodecCtx->bit_rate,mSampleRate, ExportFFmpegWMAOptions::iWMASampleRates[0], ExportFFmpegWMAOptions::iWMASampleRates[4], &ExportFFmpegWMAOptions::iWMASampleRates[0]); break; case FMT_OTHER: av_dict_set(&mEncAudioStream->metadata, "language", gPrefs->Read(wxT("/FileFormats/FFmpegLanguage"),wxT("")).ToUTF8(), 0); mEncAudioCodecCtx->sample_rate = gPrefs->Read(wxT("/FileFormats/FFmpegSampleRate"),(long)0); if (mEncAudioCodecCtx->sample_rate != 0) mSampleRate = mEncAudioCodecCtx->sample_rate; mEncAudioCodecCtx->bit_rate = gPrefs->Read(wxT("/FileFormats/FFmpegBitRate"), (long)0); strncpy((char *)&mEncAudioCodecCtx->codec_tag,gPrefs->Read(wxT("/FileFormats/FFmpegTag"),wxT("")).mb_str(wxConvUTF8),4); mEncAudioCodecCtx->global_quality = gPrefs->Read(wxT("/FileFormats/FFmpegQuality"),(long)-99999); mEncAudioCodecCtx->cutoff = gPrefs->Read(wxT("/FileFormats/FFmpegCutOff"),(long)0); mEncAudioCodecCtx->flags2 = 0; if (gPrefs->Read(wxT("/FileFormats/FFmpegBitReservoir"),true)) av_dict_set(&options, "reservoir", "1", 0); if (gPrefs->Read(wxT("/FileFormats/FFmpegVariableBlockLen"),true)) mEncAudioCodecCtx->flags2 |= 0x0004; //WMA only? mEncAudioCodecCtx->compression_level = gPrefs->Read(wxT("/FileFormats/FFmpegCompLevel"),-1); mEncAudioCodecCtx->frame_size = gPrefs->Read(wxT("/FileFormats/FFmpegFrameSize"),(long)0); //FIXME The list of supported options for the seleced encoder should be extracted instead of a few hardcoded set_dict_int(&options, "lpc_coeff_precision", gPrefs->Read(wxT("/FileFormats/FFmpegLPCCoefPrec"),(long)0)); set_dict_int(&options, "min_prediction_order", gPrefs->Read(wxT("/FileFormats/FFmpegMinPredOrder"),(long)-1)); set_dict_int(&options, "max_prediction_order", gPrefs->Read(wxT("/FileFormats/FFmpegMaxPredOrder"),(long)-1)); set_dict_int(&options, "min_partition_order", gPrefs->Read(wxT("/FileFormats/FFmpegMinPartOrder"),(long)-1)); set_dict_int(&options, "max_partition_order", gPrefs->Read(wxT("/FileFormats/FFmpegMaxPartOrder"),(long)-1)); set_dict_int(&options, "prediction_order_method", gPrefs->Read(wxT("/FileFormats/FFmpegPredOrderMethod"),(long)0)); set_dict_int(&options, "muxrate", gPrefs->Read(wxT("/FileFormats/FFmpegMuxRate"),(long)0)); mEncFormatCtx->packet_size = gPrefs->Read(wxT("/FileFormats/FFmpegPacketSize"),(long)0); codec = avcodec_find_encoder_by_name(gPrefs->Read(wxT("/FileFormats/FFmpegCodec")).ToUTF8()); if (!codec) mEncAudioCodecCtx->codec_id = mEncFormatDesc->audio_codec; break; default: return false; } // This happens if user refused to resample the project if (mSampleRate == 0) return false; if (mEncAudioCodecCtx->global_quality >= 0) { mEncAudioCodecCtx->flags |= CODEC_FLAG_QSCALE; } else mEncAudioCodecCtx->global_quality = 0; mEncAudioCodecCtx->global_quality = mEncAudioCodecCtx->global_quality * FF_QP2LAMBDA; mEncAudioCodecCtx->sample_rate = mSampleRate; mEncAudioCodecCtx->channels = mChannels; mEncAudioCodecCtx->time_base.num = 1; mEncAudioCodecCtx->time_base.den = mEncAudioCodecCtx->sample_rate; mEncAudioCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16; mEncAudioCodecCtx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; if (mEncAudioCodecCtx->codec_id == AV_CODEC_ID_AC3) { // As of Jan 4, 2011, the default AC3 encoder only accept SAMPLE_FMT_FLT samples. // But, currently, Audacity only supports SAMPLE_FMT_S16. So, for now, look for the // "older" AC3 codec. this is not a proper solution, but will suffice until other // encoders no longer support SAMPLE_FMT_S16. codec = avcodec_find_encoder_by_name("ac3_fixed"); } if (!codec) { codec = avcodec_find_encoder(mEncAudioCodecCtx->codec_id); } // Is the required audio codec compiled into libavcodec? if (codec == NULL) { wxMessageBox(wxString::Format(_("FFmpeg cannot find audio codec 0x%x.\nSupport for this codec is probably not compiled in."), (unsigned int) mEncAudioCodecCtx->codec_id), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } if (codec->sample_fmts) { for (int i=0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) { enum AVSampleFormat fmt = codec->sample_fmts[i]; if ( fmt == AV_SAMPLE_FMT_U8 || fmt == AV_SAMPLE_FMT_U8P || fmt == AV_SAMPLE_FMT_S16 || fmt == AV_SAMPLE_FMT_S16P || fmt == AV_SAMPLE_FMT_S32 || fmt == AV_SAMPLE_FMT_S32P || fmt == AV_SAMPLE_FMT_FLT || fmt == AV_SAMPLE_FMT_FLTP) { mEncAudioCodecCtx->sample_fmt = fmt; } if ( fmt == AV_SAMPLE_FMT_S16 || fmt == AV_SAMPLE_FMT_S16P) break; } } if (mEncFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) { mEncAudioCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; mEncFormatCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; } // Open the codec. if (avcodec_open2(mEncAudioCodecCtx, codec, &options) < 0) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't open audio codec 0x%x."),mEncAudioCodecCtx->codec_id), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } default_frame_size = mEncAudioCodecCtx->frame_size; if (default_frame_size == 0) default_frame_size = 1024; // arbitrary non zero value; wxLogDebug(wxT("FFmpeg : Audio Output Codec Frame Size: %d samples."), mEncAudioCodecCtx->frame_size); // The encoder may require a minimum number of raw audio samples for each encoding but we can't // guarantee we'll get this minimum each time an audio frame is decoded from the input file so // we use a FIFO to store up incoming raw samples until we have enough for one call to the codec. mEncAudioFifo = av_fifo_alloc(1024); mEncAudioFifoOutBufSiz = 2*MAX_AUDIO_PACKET_SIZE; // Allocate a buffer to read OUT of the FIFO into. The FIFO maintains its own buffer internally. if ((mEncAudioFifoOutBuf = (uint8_t*)av_malloc(mEncAudioFifoOutBufSiz)) == NULL) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't allocate buffer to read into from audio FIFO.")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } return true; }
int mpae_init_lavc(audio_encoder_t *encoder) { encoder->params.samples_per_frame = encoder->params.sample_rate; encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8; if(!lavc_param_acodec) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); return 0; } if(!avcodec_inited){ avcodec_init(); avcodec_register_all(); avcodec_inited=1; } lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec); if (!lavc_acodec) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec); return 0; } if(lavc_param_atag == 0) { #if defined(USE_LIBAVFORMAT) || defined(USE_LIBAVFORMAT_SO) lavc_param_atag = av_codec_get_tag(mp_wav_taglists, lavc_acodec->id); #else lavc_param_atag = lavc_find_atag(lavc_param_acodec); #endif if(!lavc_param_atag) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); return 0; } } lavc_actx = avcodec_alloc_context(); if(lavc_actx == NULL) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); return 0; } // put sample parameters lavc_actx->channels = encoder->params.channels; lavc_actx->sample_rate = encoder->params.sample_rate; lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate * 1000; /* * Special case for adpcm_ima_wav. * The bitrate is only dependent on samplerate. * We have to known frame_size and block_align in advance, * so I just copied the code from libavcodec/adpcm.c * * However, ms adpcm_ima_wav uses a block_align of 2048, * lavc defaults to 1024 */ if(lavc_param_atag == 0x11) { int blkalign = 2048; int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; } if((lavc_param_audio_global_header&1) /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; } if(lavc_param_audio_global_header&2){ lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; } if(avcodec_open(lavc_actx, lavc_acodec) < 0) { mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); return 0; } if(lavc_param_atag == 0x11) { lavc_actx->block_align = 2048; lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; } encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels; encoder->bind = bind_lavc; encoder->get_frame_size = get_frame_size; encoder->encode = encode_lavc; encoder->close = close_lavc; return 1; }
static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) { lavf_priv_t *priv= demuxer->priv; AVStream *st= avfc->streams[i]; AVCodecContext *codec= st->codec; char *stream_type = NULL; int stream_id; AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0); AVMetadataTag *title= av_metadata_get(st->metadata, "title", NULL, 0); int g, override_tag = av_codec_get_tag(mp_codecid_override_taglists, codec->codec_id); // For some formats (like PCM) always trust CODEC_ID_* more than codec_tag if (override_tag) codec->codec_tag = override_tag; switch(codec->codec_type){ case CODEC_TYPE_AUDIO:{ WAVEFORMATEX *wf; sh_audio_t* sh_audio; sh_audio = new_sh_audio_aid(demuxer, i, priv->audio_streams, lang ? lang->value : NULL); if(!sh_audio) break; stream_type = "audio"; priv->astreams[priv->audio_streams] = i; wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1); // mp4a tag is used for all mp4 files no matter what they actually contain if(codec->codec_tag == MKTAG('m', 'p', '4', 'a')) codec->codec_tag= 0; if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id); wf->wFormatTag= codec->codec_tag; wf->nChannels= codec->channels; wf->nSamplesPerSec= codec->sample_rate; wf->nAvgBytesPerSec= codec->bit_rate/8; wf->nBlockAlign= codec->block_align ? codec->block_align : 1; wf->wBitsPerSample= codec->bits_per_coded_sample; wf->cbSize= codec->extradata_size; if(codec->extradata_size) memcpy(wf + 1, codec->extradata, codec->extradata_size); sh_audio->wf= wf; sh_audio->audio.dwSampleSize= codec->block_align; if(codec->frame_size && codec->sample_rate){ sh_audio->audio.dwScale=codec->frame_size; sh_audio->audio.dwRate= codec->sample_rate; }else{ sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8; sh_audio->audio.dwRate = codec->bit_rate; } g= av_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate); sh_audio->audio.dwScale /= g; sh_audio->audio.dwRate /= g; // printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align); sh_audio->ds= demuxer->audio; sh_audio->format= codec->codec_tag; sh_audio->channels= codec->channels; sh_audio->samplerate= codec->sample_rate; /* in opencore : try_decode_frame() delete in libavformat/utils.c ,so some parame maybe not be get so if samplerate no get in header, then give a fix value 44100 */ if(!sh_audio->channels) sh_audio->channels = 2; if(!sh_audio->samplerate) sh_audio->samplerate = 44100; sh_audio->i_bps= codec->bit_rate/8; switch (codec->codec_id) { case CODEC_ID_PCM_S8: case CODEC_ID_PCM_U8: sh_audio->samplesize = 1; break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: case CODEC_ID_PCM_U16BE: sh_audio->samplesize = 2; break; case CODEC_ID_PCM_ALAW: sh_audio->format = 0x6; break; case CODEC_ID_PCM_MULAW: sh_audio->format = 0x7; break; } if (title && title->value) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", priv->audio_streams, title->value); if (st->disposition & AV_DISPOSITION_DEFAULT) sh_audio->default_track = 1; if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V); // select the first audio stream if (!demuxer->audio->sh) { demuxer->audio->id = i; demuxer->audio->sh= demuxer->a_streams[i]; } else st->discard= AVDISCARD_ALL; stream_id = priv->audio_streams++; break; } case CODEC_TYPE_VIDEO:{ sh_video_t* sh_video; BITMAPINFOHEADER *bih; sh_video=new_sh_video_vid(demuxer, i, priv->video_streams); if(!sh_video) break; stream_type = "video"; priv->vstreams[priv->video_streams] = i; bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1); if(codec->codec_id == CODEC_ID_RAWVIDEO) { switch (codec->pix_fmt) { case PIX_FMT_RGB24: codec->codec_tag= MKTAG(24, 'B', 'G', 'R'); } } if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id); bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size; if(!codec->width || !codec->height){ codec->width = 16*4; codec->height = 9*4; } bih->biWidth= codec->width; bih->biHeight= codec->height; bih->biBitCount= codec->bits_per_coded_sample; bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8; bih->biCompression= codec->codec_tag; sh_video->bih= bih; sh_video->disp_w= codec->width; sh_video->disp_h= codec->height; if (st->time_base.den) { /* if container has time_base, use that */ sh_video->video.dwRate= st->time_base.den; sh_video->video.dwScale= st->time_base.num; } else { sh_video->video.dwRate= codec->time_base.den; sh_video->video.dwScale= codec->time_base.num; } sh_video->fps=av_q2d(st->r_frame_rate); sh_video->frametime=1/av_q2d(st->r_frame_rate); sh_video->format=bih->biCompression; if(st->sample_aspect_ratio.num) sh_video->aspect = codec->width * st->sample_aspect_ratio.num / (float)(codec->height * st->sample_aspect_ratio.den); else sh_video->aspect=codec->width * codec->sample_aspect_ratio.num / (float)(codec->height * codec->sample_aspect_ratio.den); sh_video->rotation_degrees = st->rotation_degrees; sh_video->i_bps=codec->bit_rate/8; if (title && title->value) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", priv->video_streams, title->value); mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", codec->width, codec->sample_aspect_ratio.num, codec->height, codec->sample_aspect_ratio.den); sh_video->ds= demuxer->video; if(codec->extradata_size) memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size); if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); /* short biPlanes; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant; */ if(demuxer->video->id != i && demuxer->video->id != -1) st->discard= AVDISCARD_ALL; else{ demuxer->video->id = i; demuxer->video->sh= demuxer->v_streams[i]; } stream_id = priv->video_streams++; break; } case CODEC_TYPE_SUBTITLE:{ sh_sub_t* sh_sub; char type; /* only support text subtitles for now */ if(codec->codec_id == CODEC_ID_TEXT) type = 't'; else if(codec->codec_id == CODEC_ID_MOV_TEXT) type = 'm'; else if(codec->codec_id == CODEC_ID_SSA) type = 'a'; else if(codec->codec_id == CODEC_ID_DVD_SUBTITLE) type = 'v'; else if(codec->codec_id == CODEC_ID_XSUB) type = 'x'; else if(codec->codec_id == CODEC_ID_DVB_SUBTITLE) type = 'b'; else if(codec->codec_id == CODEC_ID_DVB_TELETEXT) type = 'd'; else if(codec->codec_id == CODEC_ID_HDMV_PGS_SUBTITLE) type = 'p'; else break; sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams, lang ? lang->value : NULL); if(!sh_sub) break; stream_type = "subtitle"; priv->sstreams[priv->sub_streams] = i; sh_sub->type = type; if (codec->extradata_size) { sh_sub->extradata = malloc(codec->extradata_size); memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size); sh_sub->extradata_len = codec->extradata_size; } if (title && title->value) mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", priv->sub_streams, title->value); if (st->disposition & AV_DISPOSITION_DEFAULT) sh_sub->default_track = 1; stream_id = priv->sub_streams++; break; } case CODEC_TYPE_ATTACHMENT:{ if (st->codec->codec_id == CODEC_ID_TTF) demuxer_add_attachment(demuxer, st->filename, "application/x-truetype-font", codec->extradata, codec->extradata_size); break; } default: st->discard= AVDISCARD_ALL; } if (stream_type) { AVCodec *avc = avcodec_find_decoder(codec->codec_id); const char *codec_name = avc ? avc->name : "unknown"; if (strcmp("tta", codec_name) == 0) demuxer->ttaflag = 1; if (!avc && *stream_type == 's' && demuxer->s_streams[stream_id]) codec_name = sh_sub_type2str(((sh_sub_t *)demuxer->s_streams[stream_id])->type); mp_msg(MSGT_DEMUX, MSGL_INFO, "[lavf] stream %d: %s (%s), -%cid %d", i, stream_type, codec_name, *stream_type, stream_id); if (lang && lang->value && *stream_type != 'v') mp_msg(MSGT_DEMUX, MSGL_INFO, ", -%clang %s", *stream_type, lang->value); if (title && title->value) mp_msg(MSGT_DEMUX, MSGL_INFO, ", %s", title->value); mp_msg(MSGT_DEMUX, MSGL_INFO, "\n"); } }
static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ AVFormatContext *avfc; AVFormatParameters ap; AVOption *opt; lavf_priv_t *priv= demuxer->priv; int i,g; char mp_filename[256]="mp:"; memset(&ap, 0, sizeof(AVFormatParameters)); stream_seek(demuxer->stream, 0); register_protocol(&mp_protocol); avfc = av_alloc_format_context(); if (correct_pts) avfc->flags |= AVFMT_FLAG_GENPTS; if (index_mode == 0) avfc->flags |= AVFMT_FLAG_IGNIDX; ap.prealloced_context = 1; if(opt_probesize) { double d = (double) opt_probesize; opt = av_set_double(avfc, "probesize", opt_probesize); if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %.3f\r\n", d); } if(demuxer->stream->url) strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3); else strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3); url_fopen(&priv->pb, mp_filename, URL_RDONLY); ((URLContext*)(priv->pb.opaque))->priv_data= demuxer->stream; if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n"); return NULL; } priv->avfc= avfc; if(av_find_stream_info(avfc) < 0){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n"); return NULL; } if(avfc->title [0]) demux_info_add(demuxer, "name" , avfc->title ); if(avfc->author [0]) demux_info_add(demuxer, "author" , avfc->author ); if(avfc->copyright[0]) demux_info_add(demuxer, "copyright", avfc->copyright); if(avfc->comment [0]) demux_info_add(demuxer, "comments" , avfc->comment ); if(avfc->album [0]) demux_info_add(demuxer, "album" , avfc->album ); // if(avfc->year ) demux_info_add(demuxer, "year" , avfc->year ); // if(avfc->track ) demux_info_add(demuxer, "track" , avfc->track ); if(avfc->genre [0]) demux_info_add(demuxer, "genre" , avfc->genre ); for(i=0; i<avfc->nb_streams; i++){ AVStream *st= avfc->streams[i]; AVCodecContext *codec= st->codec; switch(codec->codec_type){ case CODEC_TYPE_AUDIO:{ WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1); sh_audio_t* sh_audio; if(priv->audio_streams >= MAX_A_STREAMS) break; sh_audio=new_sh_audio(demuxer, i); if(!sh_audio) break; priv->astreams[priv->audio_streams] = i; priv->audio_streams++; if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id); wf->wFormatTag= codec->codec_tag; wf->nChannels= codec->channels; wf->nSamplesPerSec= codec->sample_rate; wf->nAvgBytesPerSec= codec->bit_rate/8; wf->nBlockAlign= codec->block_align ? codec->block_align : 1; wf->wBitsPerSample= codec->bits_per_sample; wf->cbSize= codec->extradata_size; if(codec->extradata_size){ memcpy( wf + 1, codec->extradata, codec->extradata_size); } sh_audio->wf= wf; sh_audio->audio.dwSampleSize= codec->block_align; if(codec->frame_size && codec->sample_rate){ sh_audio->audio.dwScale=codec->frame_size; sh_audio->audio.dwRate= codec->sample_rate; }else{ sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8; sh_audio->audio.dwRate = codec->bit_rate; } g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate); sh_audio->audio.dwScale /= g; sh_audio->audio.dwRate /= g; // printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align); sh_audio->ds= demuxer->audio; sh_audio->format= codec->codec_tag; sh_audio->channels= codec->channels; sh_audio->samplerate= codec->sample_rate; sh_audio->i_bps= codec->bit_rate/8; switch (codec->codec_id) { case CODEC_ID_PCM_S8: case CODEC_ID_PCM_U8: sh_audio->samplesize = 1; break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: case CODEC_ID_PCM_U16BE: sh_audio->samplesize = 2; break; case CODEC_ID_PCM_ALAW: sh_audio->format = 0x6; break; case CODEC_ID_PCM_MULAW: sh_audio->format = 0x7; break; } if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V); if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3)) || (demuxer->audio->id == i || demuxer->audio->id == -1) ) { demuxer->audio->id = i; demuxer->audio->sh= demuxer->a_streams[i]; } else st->discard= AVDISCARD_ALL; break;} case CODEC_TYPE_VIDEO:{ sh_video_t* sh_video; BITMAPINFOHEADER *bih; if(priv->video_streams >= MAX_V_STREAMS) break; sh_video=new_sh_video(demuxer, i); if(!sh_video) break; priv->vstreams[priv->video_streams] = i; priv->video_streams++; bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1); if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id); bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size; bih->biWidth= codec->width; bih->biHeight= codec->height; bih->biBitCount= codec->bits_per_sample; bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8; bih->biCompression= codec->codec_tag; sh_video->bih= bih; sh_video->disp_w= codec->width; sh_video->disp_h= codec->height; if (st->time_base.den) { /* if container has time_base, use that */ sh_video->video.dwRate= st->time_base.den; sh_video->video.dwScale= st->time_base.num; } else { sh_video->video.dwRate= codec->time_base.den; sh_video->video.dwScale= codec->time_base.num; } sh_video->fps=av_q2d(st->r_frame_rate); sh_video->frametime=1/av_q2d(st->r_frame_rate); sh_video->format = bih->biCompression; sh_video->aspect= codec->width * codec->sample_aspect_ratio.num / (float)(codec->height * codec->sample_aspect_ratio.den); sh_video->i_bps= codec->bit_rate/8; mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", codec->width, codec->sample_aspect_ratio.num, codec->height, codec->sample_aspect_ratio.den); sh_video->ds= demuxer->video; if(codec->extradata_size) memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size); if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); /* short biPlanes; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant;*/ if(demuxer->video->id != i && demuxer->video->id != -1) st->discard= AVDISCARD_ALL; else{ demuxer->video->id = i; demuxer->video->sh= demuxer->v_streams[i]; } break;} default: st->discard= AVDISCARD_ALL; } } mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams); mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD); if(!priv->audio_streams) demuxer->audio->id=-2; // nosound // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio; if(!priv->video_streams){ if(!priv->audio_streams){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n"); return NULL; } demuxer->video->id=-2; // audio-only } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video; return demuxer; }
int groove_file_save_as(struct GrooveFile *file, const char *filename) { struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file; // detect output format AVOutputFormat *ofmt = av_guess_format(f->ic->iformat->name, f->ic->filename, NULL); if (!ofmt) { return GrooveErrorUnknownFormat; } // allocate output media context f->oc = avformat_alloc_context(); if (!f->oc) { cleanup_save(file); return GrooveErrorNoMem; } f->oc->oformat = ofmt; snprintf(f->oc->filename, sizeof(f->oc->filename), "%s", filename); // open output file if needed if (!(ofmt->flags & AVFMT_NOFILE)) { if (avio_open(&f->oc->pb, f->oc->filename, AVIO_FLAG_WRITE) < 0) { cleanup_save(file); return GrooveErrorFileSystem; } f->tempfile_exists = 1; } if (f->ic->nb_streams > INT_MAX) { cleanup_save(file); return GrooveErrorTooManyStreams; } int stream_count = (int)f->ic->nb_streams; // add all the streams for (int i = 0; i < stream_count; i++) { AVStream *in_stream = f->ic->streams[i]; AVStream *out_stream = avformat_new_stream(f->oc, NULL); if (!out_stream) { cleanup_save(file); return GrooveErrorNoMem; } out_stream->id = in_stream->id; out_stream->disposition = in_stream->disposition; out_stream->time_base = in_stream->time_base; AVCodecContext *icodec = in_stream->codec; AVCodecContext *ocodec = out_stream->codec; ocodec->bits_per_raw_sample = icodec->bits_per_raw_sample; ocodec->chroma_sample_location = icodec->chroma_sample_location; ocodec->codec_id = icodec->codec_id; ocodec->codec_type = icodec->codec_type; if (!ocodec->codec_tag) { if (!f->oc->oformat->codec_tag || av_codec_get_id (f->oc->oformat->codec_tag, icodec->codec_tag) == ocodec->codec_id || av_codec_get_tag(f->oc->oformat->codec_tag, icodec->codec_id) <= 0) ocodec->codec_tag = icodec->codec_tag; } ocodec->bit_rate = icodec->bit_rate; ocodec->rc_max_rate = icodec->rc_max_rate; ocodec->rc_buffer_size = icodec->rc_buffer_size; ocodec->field_order = icodec->field_order; uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE; if (extra_size > INT_MAX) { cleanup_save(file); return GrooveErrorEncoding; } ocodec->extradata = allocate<uint8_t>(extra_size); if (!ocodec->extradata) { cleanup_save(file); return GrooveErrorNoMem; } memcpy(ocodec->extradata, icodec->extradata, icodec->extradata_size); ocodec->extradata_size = icodec->extradata_size; switch (ocodec->codec_type) { case AVMEDIA_TYPE_AUDIO: ocodec->channel_layout = icodec->channel_layout; ocodec->sample_rate = icodec->sample_rate; ocodec->channels = icodec->channels; ocodec->frame_size = icodec->frame_size; ocodec->audio_service_type = icodec->audio_service_type; ocodec->block_align = icodec->block_align; break; case AVMEDIA_TYPE_VIDEO: ocodec->pix_fmt = icodec->pix_fmt; ocodec->width = icodec->width; ocodec->height = icodec->height; ocodec->has_b_frames = icodec->has_b_frames; if (!ocodec->sample_aspect_ratio.num) { ocodec->sample_aspect_ratio = out_stream->sample_aspect_ratio = in_stream->sample_aspect_ratio.num ? in_stream->sample_aspect_ratio : icodec->sample_aspect_ratio.num ? icodec->sample_aspect_ratio : AVRational{0, 1}; } break; case AVMEDIA_TYPE_SUBTITLE: ocodec->width = icodec->width; ocodec->height = icodec->height; break; case AVMEDIA_TYPE_DATA: case AVMEDIA_TYPE_ATTACHMENT: break; default: cleanup_save(file); return GrooveErrorEncoding; } } // set metadata av_dict_copy(&f->oc->metadata, f->ic->metadata, 0); if (avformat_write_header(f->oc, NULL) < 0) { cleanup_save(file); return GrooveErrorEncoding; } AVPacket *pkt = &f->audio_pkt; for (;;) { int err = av_read_frame(f->ic, pkt); if (err == AVERROR_EOF) { break; } else if (err < 0) { cleanup_save(file); return GrooveErrorDecoding; } if (av_write_frame(f->oc, pkt) < 0) { cleanup_save(file); return GrooveErrorEncoding; } av_free_packet(pkt); } if (av_write_trailer(f->oc) < 0) { cleanup_save(file); return GrooveErrorEncoding; } f->tempfile_exists = 0; cleanup_save(file); return 0; }
static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) { lavf_priv_t *priv= demuxer->priv; AVStream *st= avfc->streams[i]; AVCodecContext *codec= st->codec; int g; switch(codec->codec_type){ case CODEC_TYPE_AUDIO:{ WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1); sh_audio_t* sh_audio; if(priv->audio_streams >= MAX_A_STREAMS) break; sh_audio=new_sh_audio(demuxer, i); mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "lavf", i); if(!sh_audio) break; priv->astreams[priv->audio_streams] = i; priv->audio_streams++; // mp4a tag is used for all mp4 files no matter what they actually contain if(codec->codec_tag == MKTAG('m', 'p', '4', 'a')) codec->codec_tag= 0; if(codec->codec_id == CODEC_ID_ADPCM_IMA_AMV) codec->codec_tag= MKTAG('A','M','V','A'); if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id); wf->wFormatTag= codec->codec_tag; wf->nChannels= codec->channels; wf->nSamplesPerSec= codec->sample_rate; wf->nAvgBytesPerSec= codec->bit_rate/8; wf->nBlockAlign= codec->block_align ? codec->block_align : 1; wf->wBitsPerSample= codec->bits_per_sample; wf->cbSize= codec->extradata_size; if(codec->extradata_size) memcpy(wf + 1, codec->extradata, codec->extradata_size); sh_audio->wf= wf; sh_audio->audio.dwSampleSize= codec->block_align; if(codec->frame_size && codec->sample_rate){ sh_audio->audio.dwScale=codec->frame_size; sh_audio->audio.dwRate= codec->sample_rate; }else{ sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8; sh_audio->audio.dwRate = codec->bit_rate; } g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate); sh_audio->audio.dwScale /= g; sh_audio->audio.dwRate /= g; // printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align); sh_audio->ds= demuxer->audio; sh_audio->format= codec->codec_tag; sh_audio->channels= codec->channels; sh_audio->samplerate= codec->sample_rate; sh_audio->i_bps= codec->bit_rate/8; switch (codec->codec_id) { case CODEC_ID_PCM_S8: case CODEC_ID_PCM_U8: sh_audio->samplesize = 1; break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: case CODEC_ID_PCM_U16BE: sh_audio->samplesize = 2; break; case CODEC_ID_PCM_ALAW: sh_audio->format = 0x6; break; case CODEC_ID_PCM_MULAW: sh_audio->format = 0x7; break; } if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V); if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3)) || (demuxer->audio->id == i || demuxer->audio->id == -1)) { demuxer->audio->id = i; demuxer->audio->sh= demuxer->a_streams[i]; } else st->discard= AVDISCARD_ALL; break; } case CODEC_TYPE_VIDEO:{ sh_video_t* sh_video; BITMAPINFOHEADER *bih; if(priv->video_streams >= MAX_V_STREAMS) break; sh_video=new_sh_video(demuxer, i); mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "lavf", i); if(!sh_video) break; priv->vstreams[priv->video_streams] = i; priv->video_streams++; bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1); if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id); bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size; bih->biWidth= codec->width; bih->biHeight= codec->height; bih->biBitCount= codec->bits_per_sample; bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8; bih->biCompression= codec->codec_tag; sh_video->bih= bih; sh_video->disp_w= codec->width; sh_video->disp_h= codec->height; if (st->time_base.den) { /* if container has time_base, use that */ sh_video->video.dwRate= st->time_base.den; sh_video->video.dwScale= st->time_base.num; } else { sh_video->video.dwRate= codec->time_base.den; sh_video->video.dwScale= codec->time_base.num; } sh_video->fps=av_q2d(st->r_frame_rate); sh_video->frametime=1/av_q2d(st->r_frame_rate); sh_video->format=bih->biCompression; sh_video->aspect=codec->width * codec->sample_aspect_ratio.num / (float)(codec->height * codec->sample_aspect_ratio.den); sh_video->i_bps=codec->bit_rate/8; mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", codec->width, codec->sample_aspect_ratio.num, codec->height, codec->sample_aspect_ratio.den); sh_video->ds= demuxer->video; if(codec->extradata_size) memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size); if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); /* short biPlanes; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant; */ if(demuxer->video->id != i && demuxer->video->id != -1) st->discard= AVDISCARD_ALL; else{ demuxer->video->id = i; demuxer->video->sh= demuxer->v_streams[i]; } break; } case CODEC_TYPE_SUBTITLE:{ sh_sub_t* sh_sub; if(priv->sub_streams >= MAX_S_STREAMS) break; /* only support text subtitles for now */ if(codec->codec_id != CODEC_ID_TEXT) break; sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams); mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_SubtitleID, "lavf", priv->sub_streams); if(!sh_sub) break; priv->sstreams[priv->sub_streams] = i; sh_sub->type = 't'; demuxer->sub->sh = demuxer->s_streams[priv->sub_streams++]; break; } default: st->discard= AVDISCARD_ALL; } }
/***************************************************************************** * AddStream *****************************************************************************/ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) { sout_mux_sys_t *p_sys = p_mux->p_sys; const es_format_t *fmt = p_input->p_fmt; unsigned i_codec_id; msg_Dbg( p_mux, "adding input" ); if( !GetFfmpegCodec( fmt->i_cat, fmt->i_codec, &i_codec_id, NULL ) || i_codec_id == AV_CODEC_ID_NONE ) { msg_Dbg( p_mux, "couldn't find codec for fourcc '%4.4s'", (char *)&fmt->i_codec ); return VLC_EGENERIC; } unsigned opus_size[XIPH_MAX_HEADER_COUNT]; void *opus_packet[XIPH_MAX_HEADER_COUNT]; if( fmt->i_codec == VLC_CODEC_OPUS ) { unsigned count; /* Only transmits the first packet (OpusHead) */ if( xiph_SplitHeaders(opus_size, opus_packet, &count, fmt->i_extra, fmt->p_extra ) ) { count = 0; } if (count != 2 || opus_size[0] < 19) { msg_Err(p_mux, "Invalid Opus header"); return VLC_EGENERIC; } } if( fmt->i_cat != VIDEO_ES && fmt->i_cat != AUDIO_ES) { msg_Warn( p_mux, "Unhandled ES category" ); return VLC_EGENERIC; } /* */ p_input->p_sys = malloc( sizeof( int ) ); if( unlikely(p_input->p_sys == NULL) ) return VLC_ENOMEM; *((int *)p_input->p_sys) = p_sys->oc->nb_streams; /* */ AVStream *stream = avformat_new_stream( p_sys->oc, NULL); if( !stream ) { free( p_input->p_sys ); return VLC_EGENERIC; } #if (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 5, 0)) AVCodecParameters *codecpar = stream->codecpar; #else AVCodecContext *codecpar = stream->codec; #endif unsigned int i_bitrate = fmt->i_bitrate; unsigned int i_frame_rate = fmt->video.i_frame_rate; unsigned int i_frame_rate_base = fmt->video.i_frame_rate_base; switch( fmt->i_cat ) { case AUDIO_ES: codecpar->codec_type = AVMEDIA_TYPE_AUDIO; codecpar->channels = fmt->audio.i_channels; codecpar->sample_rate = fmt->audio.i_rate; stream->time_base = (AVRational){1, codecpar->sample_rate}; if (fmt->i_bitrate == 0) { msg_Warn( p_mux, "Missing audio bitrate, assuming 64k" ); i_bitrate = 64000; } break; case VIDEO_ES: if( !fmt->video.i_frame_rate || !fmt->video.i_frame_rate_base ) { msg_Warn( p_mux, "Missing frame rate, assuming 25fps" ); i_frame_rate = 25; i_frame_rate_base = 1; } else msg_Dbg( p_mux, "Muxing framerate will be %d/%d = %.2f fps", fmt->video.i_frame_rate, fmt->video.i_frame_rate_base, (double)fmt->video.i_frame_rate/(double)fmt->video.i_frame_rate_base ); codecpar->codec_type = AVMEDIA_TYPE_VIDEO; codecpar->width = fmt->video.i_visible_width; codecpar->height = fmt->video.i_visible_height; av_reduce( &codecpar->sample_aspect_ratio.num, &codecpar->sample_aspect_ratio.den, fmt->video.i_sar_num, fmt->video.i_sar_den, 1 << 30 /* something big */ ); msg_Dbg(p_mux, "Muxing aspect ratio will be %d/%d", fmt->video.i_sar_num, fmt->video.i_sar_den); stream->sample_aspect_ratio.den = codecpar->sample_aspect_ratio.den; stream->sample_aspect_ratio.num = codecpar->sample_aspect_ratio.num; stream->time_base.den = i_frame_rate; stream->time_base.num = i_frame_rate_base; if (fmt->i_bitrate == 0) { msg_Warn( p_mux, "Missing video bitrate, assuming 512k" ); i_bitrate = 512000; } else msg_Dbg( p_mux, "Muxing video bitrate will be %d", fmt->i_bitrate ); break; default: vlc_assert_unreachable(); } codecpar->bit_rate = i_bitrate; codecpar->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id ); if( !codecpar->codec_tag && i_codec_id == AV_CODEC_ID_MP2 ) { i_codec_id = AV_CODEC_ID_MP3; codecpar->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id ); } codecpar->codec_id = i_codec_id; if( fmt->i_extra ) { if( fmt->i_codec == VLC_CODEC_OPUS ) { codecpar->extradata_size = opus_size[0]; codecpar->extradata = av_malloc( opus_size[0] ); memcpy( codecpar->extradata, opus_packet[0], opus_size[0] ); } else { codecpar->extradata_size = fmt->i_extra; codecpar->extradata = av_malloc( fmt->i_extra ); memcpy( codecpar->extradata, fmt->p_extra, fmt->i_extra ); } } return VLC_SUCCESS; }