From 1d6596dc61677f7e64c29c7e3f44e6639e1c7c46 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 22 Oct 2026 00:17:16 +0200 Subject: [PATCH] Check resampler tail duration and actual 1080p to 720p conversion --- tests/test_video.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/test_video.c b/tests/test_video.c index 80857601..61ea81c2 100644 --- a/tests/test_video.c +++ b/tests/test_video.c @@ -38,6 +38,7 @@ static void done(void* arg, int error, const struct video_info* info) { #ifdef HAVE_FFMPEG static char directory[256], source[512], destination[512]; static int audio_offset_ms; +static int audio_rate = 32000, fixture_width = 64, fixture_height = 64; #ifdef __linux__ enum video_fault { NO_FAULT, WRITE_FAULT, FLUSH_FAULT, CLOSE_FAULT, PUBLISH_FAULT, TRAILER_FAULT, @@ -149,7 +150,7 @@ static void fixture(const char* path, const char* format, enum AVCodecID video, assert(avformat_alloc_output_context2(&mux, NULL, format, path) >= 0); const AVCodec* codec = avcodec_find_encoder(video); assert(codec); AVCodecContext* enc = avcodec_alloc_context3(codec); assert(enc); - enc->width = enc->height = 64; enc->pix_fmt = AV_PIX_FMT_YUV420P; + enc->width = fixture_width; enc->height = fixture_height; enc->pix_fmt = AV_PIX_FMT_YUV420P; enc->time_base = (AVRational){1, 10}; enc->framerate = (AVRational){10, 1}; enc->bit_rate = 100000; enc->gop_size = 12; enc->max_b_frames = 2; enc->thread_count = 1; if (mux->oformat->flags & AVFMT_GLOBALHEADER) enc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; @@ -162,7 +163,7 @@ static void fixture(const char* path, const char* format, enum AVCodecID video, if (audio != AV_CODEC_ID_NONE) { codec = avcodec_find_encoder(audio); assert(codec); aenc = avcodec_alloc_context3(codec); assert(aenc); - aenc->sample_rate = 32000; aenc->time_base = (AVRational){1, 32000}; + aenc->sample_rate = audio_rate; aenc->time_base = (AVRational){1, audio_rate}; #if LIBAVCODEC_VERSION_MAJOR >= 61 const void* formats; assert(avcodec_get_supported_config(aenc, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, &formats, NULL) >= 0 && formats); @@ -185,9 +186,9 @@ static void fixture(const char* path, const char* format, enum AVCodecID video, assert(av_frame_get_buffer(frame, 0) >= 0); for (int serial = 0; serial < 6; serial++) { assert(av_frame_make_writable(frame) >= 0); - for (int y = 0; y < 64; y++) memset(frame->data[0] + y * frame->linesize[0], 40 + serial * 20, 64); + for (int y = 0; y < enc->height; y++) memset(frame->data[0] + y * frame->linesize[0], 40 + serial * 20, enc->width); for (int plane = 1; plane < 3; plane++) - for (int y = 0; y < 32; y++) memset(frame->data[plane] + y * frame->linesize[plane], 128, 32); + for (int y = 0; y < enc->height / 2; y++) memset(frame->data[plane] + y * frame->linesize[plane], 128, enc->width / 2); frame->pts = serial; assert(avcodec_send_frame(enc, frame) >= 0); fixture_packets(mux, enc, stream); } @@ -289,6 +290,9 @@ static void decode_audio(const char* path, int minimum_samples, int offset_ms) { assert(avformat_find_stream_info(format, NULL) >= 0); int index = av_find_best_stream(format, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); assert(index >= 0); AVStream* stream = format->streams[index]; + int64_t end_us = av_rescale_q(stream->start_time + stream->duration, stream->time_base, AV_TIME_BASE_Q); + int64_t expected_end_us = (int64_t)offset_ms * 1000 + av_rescale(minimum_samples, 1000000, stream->codecpar->sample_rate); + assert(llabs(end_us - expected_end_us) <= 150); // Проверяется хвост ресемплера, а не только padded AAC frames. AVCodecContext* decoder = avcodec_alloc_context3(avcodec_find_decoder(stream->codecpar->codec_id)); assert(decoder); assert(avcodec_parameters_to_context(decoder, stream->codecpar) >= 0 && avcodec_open2(decoder, decoder->codec, NULL) >= 0); AVPacket* packet = av_packet_alloc(); AVFrame* frame = av_frame_alloc(); assert(packet && frame); @@ -461,6 +465,16 @@ int main(void) { fixture(source, "matroska", AV_CODEC_ID_MPEG4, AV_CODEC_ID_PCM_S16LE); prepare(ua, owner, source, destination); assert(!result_error); decode_result(destination, 6, 1); decode_audio(destination, 19584, 0); + audio_rate = 12345; // AAC не поддерживает эту частоту: реальный resample в 12000 Гц с ненулевым хвостом. + fixture(source, "matroska", AV_CODEC_ID_MPEG4, AV_CODEC_ID_PCM_S16LE); + prepare(ua, owner, source, destination); assert(!result_error); decode_result(destination, 6, 1); + decode_audio(destination, (int)av_rescale(19584, 12000, audio_rate), 0); + audio_rate = 32000; + fixture_width = 1920; fixture_height = 1080; + fixture(source, "matroska", AV_CODEC_ID_MPEG4, AV_CODEC_ID_NONE); + prepare(ua, owner, source, destination); + assert(!result_error && result_info.width == 1280 && result_info.height == 720); decode_result(destination, 6, 0); + fixture_width = fixture_height = 64; audio_offset_ms = 200; fixture(source, "matroska", AV_CODEC_ID_MPEG4, AV_CODEC_ID_PCM_S16LE); prepare(ua, owner, source, destination); assert(!result_error); decode_audio(destination, 19584, 200);