static const char *lookup_tag(int type, uint32_t tag) { for (int n = 0; mp_codec_tags[n].codec; n++) { if (mp_codec_tags[n].tag == tag) return mp_codec_tags[n].codec; } const struct AVCodecTag *av_tags[3] = {0}; switch (type) { case STREAM_VIDEO: { av_tags[0] = avformat_get_riff_video_tags(); #if HAVE_QT_TAGS av_tags[1] = avformat_get_mov_video_tags(); #endif break; } case STREAM_AUDIO: { av_tags[0] = avformat_get_riff_audio_tags(); #if HAVE_QT_TAGS av_tags[1] = avformat_get_mov_audio_tags(); #endif break; } } int id = av_codec_get_id(av_tags, tag); return id == AV_CODEC_ID_NONE ? NULL : mp_codec_from_av_codec_id(id); }
unsigned int mp_taglist_video(enum CodecID id) { const struct AVCodecTag *tags[] = {avformat_get_riff_video_tags(), NULL }; unsigned int tag = av_codec_get_tag(tags, id); if (tag) return tag; return codec_get_tag(mp_bmp_tags, id); }
FFMS_CodecID MatroskaToFFCodecID(char *Codec, void *CodecPrivate, unsigned int FourCC, unsigned int BitsPerSample) { /* Look up native codecs */ for (int i = 0; mkv_codec_tags[i].id != FFMS_ID(NONE); i++){ if (!strncmp(mkv_codec_tags[i].str, Codec, strlen(mkv_codec_tags[i].str))) { // Uncompressed and exotic format fixup // This list is incomplete FFMS_CodecID CID = mkv_codec_tags[i].id; switch (CID) { case FFMS_ID(PCM_S16LE): switch (BitsPerSample) { case 8: CID = FFMS_ID(PCM_S8); break; case 16: CID = FFMS_ID(PCM_S16LE); break; case 24: CID = FFMS_ID(PCM_S24LE); break; case 32: CID = FFMS_ID(PCM_S32LE); break; } break; case FFMS_ID(PCM_S16BE): switch (BitsPerSample) { case 8: CID = FFMS_ID(PCM_S8); break; case 16: CID = FFMS_ID(PCM_S16BE); break; case 24: CID = FFMS_ID(PCM_S24BE); break; case 32: CID = FFMS_ID(PCM_S32BE); break; } break; default: break; } return CID; } } /* Video codecs for "avi in mkv" mode */ const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), 0 }; if (!strcmp(Codec, "V_MS/VFW/FOURCC")) { FFMS_BITMAPINFOHEADER *b = reinterpret_cast<FFMS_BITMAPINFOHEADER *>(CodecPrivate); return av_codec_get_id(tags, b->biCompression); } if (!strcmp(Codec, "V_FOURCC")) { return av_codec_get_id(tags, FourCC); } // FIXME /* Audio codecs for "acm in mkv" mode */ //#include "Mmreg.h" //((WAVEFORMATEX *)TI->CodecPrivate)->wFormatTag /* Fixup for uncompressed video formats */ /* Fixup for uncompressed audio formats */ return FFMS_ID(NONE); }
void mp_set_codec_from_tag(struct sh_stream *sh) { switch (sh->type) { case STREAM_VIDEO: sh->codec = lookup_tag(mp_video_codec_tags, avformat_get_riff_video_tags(), sh->format); break; case STREAM_AUDIO: sh->codec = lookup_tag(mp_audio_codec_tags, avformat_get_riff_audio_tags(), sh->format); break; default: ; } }
bool FFmpegBaseWriter::open(const char* filename, int fourcc, double fps, int width, int height, bool iscolor, bool need_encode) { static const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 }; enum AVCodecID id = av_codec_get_id(table, fourcc); media_stream_params_t params; params.height_video = height; params.width_video = width; params.video_fps = fps; params.codec_id = id; stream_ = alloc_video_stream(filename, ¶ms, need_encode); channels_ = iscolor ? 3 : 1; return true; }
static int dshow_add_device(AVFormatContext *avctx, enum dshowDeviceType devtype) { struct dshow_ctx *ctx = avctx->priv_data; AM_MEDIA_TYPE type; AVCodecParameters *par; AVStream *st; int ret = AVERROR(EIO); st = avformat_new_stream(avctx, NULL); if (!st) { ret = AVERROR(ENOMEM); goto error; } st->id = devtype; ctx->capture_filter[devtype]->stream_index = st->index; libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type); par = st->codecpar; if (devtype == VideoDevice) { BITMAPINFOHEADER *bih = NULL; AVRational time_base; if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) { VIDEOINFOHEADER *v = (void *) type.pbFormat; time_base = (AVRational) { v->AvgTimePerFrame, 10000000 }; bih = &v->bmiHeader; } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) { VIDEOINFOHEADER2 *v = (void *) type.pbFormat; time_base = (AVRational) { v->AvgTimePerFrame, 10000000 }; bih = &v->bmiHeader; } if (!bih) { av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n"); goto error; } st->avg_frame_rate = av_inv_q(time_base); st->r_frame_rate = av_inv_q(time_base); par->codec_type = AVMEDIA_TYPE_VIDEO; par->width = bih->biWidth; par->height = bih->biHeight; par->codec_tag = bih->biCompression; par->format = dshow_pixfmt(bih->biCompression, bih->biBitCount); if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) { av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n"); par->color_range = AVCOL_RANGE_MPEG; // just in case it needs this... } if (par->format == AV_PIX_FMT_NONE) { const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL }; par->codec_id = av_codec_get_id(tags, bih->biCompression); if (par->codec_id == AV_CODEC_ID_NONE) { av_log(avctx, AV_LOG_ERROR, "Unknown compression type. " "Please report type 0x%X.\n", (int) bih->biCompression); return AVERROR_PATCHWELCOME; } par->bits_per_coded_sample = bih->biBitCount; } else { par->codec_id = AV_CODEC_ID_RAWVIDEO; if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) { par->bits_per_coded_sample = bih->biBitCount; par->extradata = av_malloc(9 + AV_INPUT_BUFFER_PADDING_SIZE); if (par->extradata) { par->extradata_size = 9; memcpy(par->extradata, "BottomUp", 9); } } } } else { WAVEFORMATEX *fx = NULL; if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) { fx = (void *) type.pbFormat; } if (!fx) { av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n"); goto error; } par->codec_type = AVMEDIA_TYPE_AUDIO; par->format = sample_fmt_bits_per_sample(fx->wBitsPerSample); par->codec_id = waveform_codec_id(par->format); par->sample_rate = fx->nSamplesPerSec; par->channels = fx->nChannels; } avpriv_set_pts_info(st, 64, 1, 10000000); ret = 0; error: return ret; }
/** * Cycle through available formats using the specified pin, * try to set parameters specified through AVOptions and if successful * return 1 in *pformat_set. * If pformat_set is NULL, list all pin capabilities. */ static void dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, IPin *pin, int *pformat_set) { struct dshow_ctx *ctx = avctx->priv_data; IAMStreamConfig *config = NULL; AM_MEDIA_TYPE *type = NULL; int format_set = 0; void *caps = NULL; int i, n, size, r; if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK) return; if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK) goto end; caps = av_malloc(size); if (!caps) goto end; for (i = 0; i < n && !format_set; i++) { r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps); if (r != S_OK) goto next; #if DSHOWDEBUG ff_print_AM_MEDIA_TYPE(type); #endif if (devtype == VideoDevice) { VIDEO_STREAM_CONFIG_CAPS *vcaps = caps; BITMAPINFOHEADER *bih; int64_t *fr; const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL }; #if DSHOWDEBUG ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps); #endif if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) { VIDEOINFOHEADER *v = (void *) type->pbFormat; fr = &v->AvgTimePerFrame; bih = &v->bmiHeader; } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) { VIDEOINFOHEADER2 *v = (void *) type->pbFormat; fr = &v->AvgTimePerFrame; bih = &v->bmiHeader; } else { goto next; } if (!pformat_set) { enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount); if (pix_fmt == AV_PIX_FMT_NONE) { enum AVCodecID codec_id = av_codec_get_id(tags, bih->biCompression); AVCodec *codec = avcodec_find_decoder(codec_id); if (codec_id == AV_CODEC_ID_NONE || !codec) { av_log(avctx, AV_LOG_INFO, " unknown compression type 0x%X", (int) bih->biCompression); } else { av_log(avctx, AV_LOG_INFO, " vcodec=%s", codec->name); } } else { av_log(avctx, AV_LOG_INFO, " pixel_format=%s", av_get_pix_fmt_name(pix_fmt)); } av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n", vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy, 1e7 / vcaps->MaxFrameInterval, vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy, 1e7 / vcaps->MinFrameInterval); continue; } if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { if (ctx->video_codec_id != av_codec_get_id(tags, bih->biCompression)) goto next; } if (ctx->pixel_format != AV_PIX_FMT_NONE && ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) { goto next; } if (ctx->framerate) { int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000) / ctx->requested_framerate.num; if (framerate > vcaps->MaxFrameInterval || framerate < vcaps->MinFrameInterval) goto next; *fr = framerate; } if (ctx->requested_width && ctx->requested_height) { if (ctx->requested_width > vcaps->MaxOutputSize.cx || ctx->requested_width < vcaps->MinOutputSize.cx || ctx->requested_height > vcaps->MaxOutputSize.cy || ctx->requested_height < vcaps->MinOutputSize.cy) goto next; bih->biWidth = ctx->requested_width; bih->biHeight = ctx->requested_height; } } else { AUDIO_STREAM_CONFIG_CAPS *acaps = caps; WAVEFORMATEX *fx; #if DSHOWDEBUG ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps); #endif if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) { fx = (void *) type->pbFormat; } else { goto next; } if (!pformat_set) { av_log(avctx, AV_LOG_INFO, " min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n", acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency, acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency); continue; } if (ctx->sample_rate) { if (ctx->sample_rate > acaps->MaximumSampleFrequency || ctx->sample_rate < acaps->MinimumSampleFrequency) goto next; fx->nSamplesPerSec = ctx->sample_rate; } if (ctx->sample_size) { if (ctx->sample_size > acaps->MaximumBitsPerSample || ctx->sample_size < acaps->MinimumBitsPerSample) goto next; fx->wBitsPerSample = ctx->sample_size; } if (ctx->channels) { if (ctx->channels > acaps->MaximumChannels || ctx->channels < acaps->MinimumChannels) goto next; fx->nChannels = ctx->channels; } } if (IAMStreamConfig_SetFormat(config, type) != S_OK) goto next; format_set = 1; next: if (type->pbFormat) CoTaskMemFree(type->pbFormat); CoTaskMemFree(type); } end: IAMStreamConfig_Release(config); av_free(caps); if (pformat_set) *pformat_set = format_set; }
static void get_taglists(const struct AVCodecTag *dst[3], int audio) { dst[0] = audio ? mp_wav_tags : mp_bmp_tags; dst[1] = audio ? avformat_get_riff_audio_tags() : avformat_get_riff_video_tags(); dst[2] = NULL; }
void mp_set_video_codec_from_tag(struct sh_video *sh) { sh->gsh->codec = lookup_tag(mp_video_codec_tags, avformat_get_riff_video_tags(), sh->format); }