From: Matthieu Bouron <matthieu.bou...@stupeflix.com> --- tests/api/Makefile | 1 + tests/api/api-codec-param-test.c | 223 ++++++++++++++++++++++++++++++++++++ tests/fate/api.mak | 8 ++ tests/ref/fate/api-jpeg-codec-param | 12 ++ tests/ref/fate/api-png-codec-param | 12 ++ 5 files changed, 256 insertions(+) create mode 100644 tests/api/api-codec-param-test.c create mode 100644 tests/ref/fate/api-jpeg-codec-param create mode 100644 tests/ref/fate/api-png-codec-param
diff --git a/tests/api/Makefile b/tests/api/Makefile index 27f499f..c48c34a 100644 --- a/tests/api/Makefile +++ b/tests/api/Makefile @@ -1,6 +1,7 @@ APITESTPROGS-$(call ENCDEC, FLAC, FLAC) += api-flac APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264 APITESTPROGS-yes += api-seek +APITESTPROGS-yes += api-codec-param APITESTPROGS-$(call DEMDEC, H263, H263) += api-band APITESTPROGS += $(APITESTPROGS-yes) diff --git a/tests/api/api-codec-param-test.c b/tests/api/api-codec-param-test.c new file mode 100644 index 0000000..48aced9 --- /dev/null +++ b/tests/api/api-codec-param-test.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2015 Matthieu Bouron <matthieu.bouron stupeflix.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> +#include <libavformat/avformat.h> +#include <libavutil/pixdesc.h> +#include <libavcodec/internal.h> +#include <libavutil/avassert.h> + +static int try_decode_video_frame(AVCodecContext *codec_ctx, AVPacket *pkt, int decode) +{ + int ret = 0; + int got_frame = 0; + AVFrame *frame = NULL; + int skip_frame = codec_ctx->skip_frame; + + if (!avcodec_is_open(codec_ctx)) { + const AVCodec *codec = avcodec_find_decoder(codec_ctx->codec_id); + + ret = avcodec_open2(codec_ctx, codec, NULL); + if (ret < 0) { + av_log(codec_ctx, AV_LOG_ERROR, "Failed to open codec\n"); + goto end; + } + } + + frame = av_frame_alloc(); + if (!frame) { + av_log(NULL, AV_LOG_ERROR, "Failed to allocate frame\n"); + goto end; + } + + if (!decode && codec_ctx->codec->caps_internal & FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM) { + codec_ctx->skip_frame = AVDISCARD_ALL; + } + + do { + ret = avcodec_decode_video2(codec_ctx, frame, &got_frame, pkt); + av_assert0(decode || (!decode && !got_frame)); + if (ret < 0) + break; + pkt->data += ret; + pkt->size -= ret; + + if (got_frame) { + break; + } + } while (pkt->size > 0); + +end: + codec_ctx->skip_frame = skip_frame; + + av_frame_free(&frame); + return ret; +} + +static int find_video_stream_info(AVFormatContext *fmt_ctx, int decode) +{ + int ret = 0; + int i, done = 0; + AVPacket pkt; + + av_init_packet(&pkt); + + while (!done) { + AVCodecContext *codec_ctx = NULL; + AVStream *st; + + if ((ret = av_read_frame(fmt_ctx, &pkt)) < 0) { + av_log(fmt_ctx, AV_LOG_ERROR, "Failed to read frame\n"); + goto end; + } + + st = fmt_ctx->streams[pkt.stream_index]; + codec_ctx = st->codec; + + if (codec_ctx->codec_type != AVMEDIA_TYPE_VIDEO || + st->codec_info_nb_frames++ > 0) { + av_packet_unref(&pkt); + continue; + } + + ret = try_decode_video_frame(codec_ctx, &pkt, decode); + if (ret < 0) { + av_log(fmt_ctx, AV_LOG_ERROR, "Failed to decode video frame\n"); + goto end; + } + + av_packet_unref(&pkt); + + /* check if all video streams have demuxed a packet */ + done = 1; + for (i = 0; i < fmt_ctx->nb_streams; i++) { + st = fmt_ctx->streams[i]; + codec_ctx = st->codec; + + if (codec_ctx->codec_type != AVMEDIA_TYPE_VIDEO) + continue; + + done &= st->codec_info_nb_frames > 0; + } + } + +end: + av_packet_unref(&pkt); + + return ret < 0; +} + +static void dump_video_streams(const AVFormatContext *fmt_ctx, int decode) +{ + int i; + + for (i = 0; i < fmt_ctx->nb_streams; i++) { + const AVStream *st = fmt_ctx->streams[i]; + const AVCodecContext *codec_ctx = st->codec; + const AVRational sar = codec_ctx->sample_aspect_ratio; + + printf("stream=%d, decode=%d\n", i, decode); + printf(" width=%d\n", codec_ctx->width); + printf(" height=%d\n", codec_ctx->height); + printf(" pix_fmt=%s\n", av_get_pix_fmt_name(codec_ctx->pix_fmt)); + printf(" sar=%d/%d\n", sar.num, sar.den); + printf("\n"); + } +} + +static int open_and_probe_video_streams(AVFormatContext **fmt_ctx, const char *filename, int decode) +{ + int ret = 0; + + ret = avformat_open_input(fmt_ctx, filename, NULL, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to open input '%s'", filename); + goto end; + } + + ret = find_video_stream_info(*fmt_ctx, decode); + if (ret < 0) { + goto end; + } + + dump_video_streams(*fmt_ctx, decode); + +end: + return ret; +} + +static void check_video_streams(const AVFormatContext *fmt_ctx1, const AVFormatContext *fmt_ctx2) +{ + int i; + + av_assert0(fmt_ctx1->nb_streams == fmt_ctx2->nb_streams); + for (i = 0; i < fmt_ctx1->nb_streams; i++) { + const AVStream *st1 = fmt_ctx1->streams[i]; + const AVStream *st2 = fmt_ctx2->streams[i]; + const AVCodecContext *codec_ctx1 = st1->codec; + const AVCodecContext *codec_ctx2 = st2->codec; + const AVRational sar1 = codec_ctx1->sample_aspect_ratio; + const AVRational sar2 = codec_ctx2->sample_aspect_ratio; + + if (codec_ctx1->codec_type != AVMEDIA_TYPE_VIDEO) + continue; + + av_assert0(codec_ctx1->codec_type == codec_ctx2->codec_type); + av_assert0(codec_ctx1->width == codec_ctx2->width); + av_assert0(codec_ctx1->height == codec_ctx2->height); + av_assert0(codec_ctx1->pix_fmt == codec_ctx2->pix_fmt); + av_assert0(sar1.num == sar2.num); + av_assert0(sar1.den == sar2.den); + } +} + +int main(int argc, char* argv[]) +{ + int ret = 0; + AVFormatContext *fmt_ctx = NULL; + AVFormatContext *fmt_ctx_no_decode = NULL; + + av_register_all(); + + if (argc < 2) { + av_log(NULL, AV_LOG_ERROR, "usage: %s <input>\n", argv[0]); + return -1; + } + + if ((ret = open_and_probe_video_streams(&fmt_ctx_no_decode, argv[1], 0)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to probe '%s' without frame decoding\n", argv[1]); + goto end; + } + + if ((ret = open_and_probe_video_streams(&fmt_ctx, argv[1], 1)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to probe '%s' with frame decoding\n", argv[1]); + goto end; + } + + check_video_streams(fmt_ctx, fmt_ctx_no_decode); + +end: + avformat_close_input(&fmt_ctx); + avformat_close_input(&fmt_ctx_no_decode); + + return ret; +} diff --git a/tests/fate/api.mak b/tests/fate/api.mak index 1d18653..325f64a 100644 --- a/tests/fate/api.mak +++ b/tests/fate/api.mak @@ -20,6 +20,14 @@ fate-api-seek: CMD = run $(APITESTSDIR)/api-seek-test $(TARGET_PATH)/tests/data/ fate-api-seek: CMP = null fate-api-seek: REF = /dev/null +FATE_API_SAMPLES_LIBAVFORMAT-yes += fate-api-png-codec-param +fate-api-png-codec-param: $(APITESTSDIR)/api-codec-param-test$(EXESUF) +fate-api-png-codec-param: CMD = run $(APITESTSDIR)/api-codec-param-test $(TARGET_SAMPLES)/png1/lena-rgba.png + +FATE_API_SAMPLES_LIBAVFORMAT-yes += fate-api-jpeg-codec-param +fate-api-jpeg-codec-param: $(APITESTSDIR)/api-codec-param-test$(EXESUF) +fate-api-jpeg-codec-param: CMD = run $(APITESTSDIR)/api-codec-param-test $(TARGET_SAMPLES)/exif/image_small.jpg + FATE_API_SAMPLES-$(CONFIG_AVFORMAT) += $(FATE_API_SAMPLES_LIBAVFORMAT-yes) ifdef SAMPLES diff --git a/tests/ref/fate/api-jpeg-codec-param b/tests/ref/fate/api-jpeg-codec-param new file mode 100644 index 0000000..5ca5bc8 --- /dev/null +++ b/tests/ref/fate/api-jpeg-codec-param @@ -0,0 +1,12 @@ +stream=0, decode=0 + width=400 + height=225 + pix_fmt=yuvj422p + sar=180/180 + +stream=0, decode=1 + width=400 + height=225 + pix_fmt=yuvj422p + sar=180/180 + diff --git a/tests/ref/fate/api-png-codec-param b/tests/ref/fate/api-png-codec-param new file mode 100644 index 0000000..623c00b --- /dev/null +++ b/tests/ref/fate/api-png-codec-param @@ -0,0 +1,12 @@ +stream=0, decode=0 + width=128 + height=128 + pix_fmt=rgba + sar=2835/2835 + +stream=0, decode=1 + width=128 + height=128 + pix_fmt=rgba + sar=2835/2835 + -- 2.6.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel