Check resampler tail duration and actual 1080p to 720p conversion

This commit is contained in:
evgeny committed 2026-10-22 00:17:16 +02:00
1 parent 0653121fc4
commit 1d6596dc61
1 file changed
+18 -4
+18 -4
View File
@@ -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);