From e7bf79289e3ac2364cb543d16857dda42e1248c4 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Tue, 26 May 2020 21:35:11 -0400 Subject: [PATCH] forbid codec options which would not render in a browser --- src/validation.c | 69 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/validation.c b/src/validation.c index ce6f382..b76d903 100644 --- a/src/validation.c +++ b/src/validation.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -7,6 +8,50 @@ const AVRational t_1h = { 3600, 1 }; const AVRational t_0h = { 0, 1 }; +static int validate_video_pixel_format(enum AVPixelFormat format) +{ + switch (format) { + // Still image formats + case AV_PIX_FMT_RGB8: + case AV_PIX_FMT_RGB24: + case AV_PIX_FMT_RGB32: + case AV_PIX_FMT_RGB48: + case AV_PIX_FMT_RGBA: + + // Video frame formats + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUVJ420P: + case AV_PIX_FMT_YUV420P10LE: + case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUV422P10LE: + case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUV444P10LE: + case AV_PIX_FMT_YUV420P12LE: + case AV_PIX_FMT_YUV422P12LE: + case AV_PIX_FMT_YUV444P12LE: + return true; + + default: + return false; + } +} + +static int validate_audio_sample_format(enum AVSampleFormat format) +{ + switch (format) { + case AV_SAMPLE_FMT_FLT: + case AV_SAMPLE_FMT_FLTP: + case AV_SAMPLE_FMT_S16: + case AV_SAMPLE_FMT_S16P: + case AV_SAMPLE_FMT_S32: + case AV_SAMPLE_FMT_S32P: + return true; + + default: + return false; + } +} + int mediatools_validate_video(AVFormatContext *format) { uint64_t num_vstreams = 0; @@ -15,13 +60,31 @@ int mediatools_validate_video(AVFormatContext *format) int64_t astream_idx = -1; for (size_t i = 0; i < format->nb_streams; ++i) { - if (format->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + AVCodecParameters *codecpar = format->streams[i]->codecpar; + + if (codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { num_vstreams++; vstream_idx = i; - } - if (format->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + + if (!validate_video_pixel_format(codecpar->format)) { + printf("Found unsupported pixel format %s\n", av_get_pix_fmt_name(codecpar->format)); + return false; + } + + } else if (codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { num_astreams++; astream_idx = i; + + if (!validate_audio_sample_format(codecpar->format)) { + printf("Found unsupported audio sample format %s\n", av_get_sample_fmt_name(codecpar->format)); + return false; + } + + } else if (codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { + // Allow subtitles + } else { + printf("Unknown codec type %s\n", av_get_media_type_string(codecpar->codec_type)); + return false; } }