On Wed, Nov 25, 2015 at 03:40:15PM +0100, Matthieu Bouron wrote: > 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>
did you intend to use #include <> instead of "" ? > + > +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) { writing into this is not ok, iam not sure it should be touched at all from API users and tests/api/* could be used as example for correct API use ... > + 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); enumerating and dumping all AVOptions might be more informative [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB DNS cache poisoning attacks, popular search engine, Google internet authority dont be evil, please
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel