mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-14 13:21:28 +00:00
qtdemux: add unit test for edit list regression
File is the mp4 file from #2549 with the mdat atom zeroed out and compressed. We compress twice because apparently compressing 5MB of zeroes effectively in one run is too difficult for gzip. https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2549 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4833>
This commit is contained in:
parent
831cff876d
commit
14f0d6c18d
2 changed files with 139 additions and 0 deletions
|
@ -23,6 +23,23 @@
|
|||
#include "qtdemux.h"
|
||||
#include <glib/gprintf.h>
|
||||
#include <gst/check/gstharness.h>
|
||||
#include <gst/app/app.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define TEST_FILE_PREFIX GST_TEST_FILES_PATH G_DIR_SEPARATOR_S
|
||||
|
||||
static gboolean
|
||||
load_file (const gchar * fn, guint8 ** p_data, guint expected_len)
|
||||
{
|
||||
gsize read_len = 0;
|
||||
|
||||
if (!g_file_get_contents (fn, (gchar **) p_data, &read_len, NULL))
|
||||
return FALSE;
|
||||
|
||||
g_assert_cmpuint (read_len, ==, expected_len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -888,6 +905,127 @@ GST_START_TEST (test_qtdemux_pad_names)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_qtdemux_editlist)
|
||||
{
|
||||
const gsize editlist_mp4_size = 5322593;
|
||||
guint8 *editlist_mp4 = NULL;
|
||||
GstElement *src, *sink, *pipe;
|
||||
GstSample *sample;
|
||||
guint frame_count = 0;
|
||||
|
||||
{
|
||||
GZlibDecompressor *decompress;
|
||||
GConverterResult decomp_res;
|
||||
gsize bytes_read, gz_size, mp4_size;
|
||||
guint8 *gz_gz = NULL;
|
||||
guint8 gz[8705];
|
||||
|
||||
/* read .mp4.gz.gz */
|
||||
g_assert (load_file (TEST_FILE_PREFIX "editlists.mp4.gz.gz", &gz_gz, 3597));
|
||||
|
||||
/* mp4.gz.gz -> mp4.gz */
|
||||
decompress = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
|
||||
decomp_res = g_converter_convert (G_CONVERTER (decompress), gz_gz, 3597,
|
||||
gz, 8705, G_CONVERTER_INPUT_AT_END, &bytes_read, &gz_size, NULL);
|
||||
fail_unless_equals_int (decomp_res, G_CONVERTER_FINISHED);
|
||||
fail_unless_equals_int (bytes_read, 3597);
|
||||
fail_unless_equals_int (gz_size, 8705);
|
||||
g_object_unref (decompress);
|
||||
g_clear_pointer (&gz_gz, (GDestroyNotify) g_free);
|
||||
|
||||
editlist_mp4 = g_malloc0 (editlist_mp4_size);
|
||||
|
||||
/* mp4.gz -> mp4 */
|
||||
decompress = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
|
||||
decomp_res = g_converter_convert (G_CONVERTER (decompress), gz, 8705,
|
||||
editlist_mp4, editlist_mp4_size, G_CONVERTER_INPUT_AT_END, &bytes_read,
|
||||
&mp4_size, NULL);
|
||||
fail_unless_equals_int (decomp_res, G_CONVERTER_FINISHED);
|
||||
fail_unless_equals_int (bytes_read, 8705);
|
||||
fail_unless_equals_int (mp4_size, editlist_mp4_size);
|
||||
g_object_unref (decompress);
|
||||
}
|
||||
|
||||
fail_unless_equals_int (editlist_mp4[28 + 4], 'm');
|
||||
fail_unless_equals_int (editlist_mp4[28 + 5], 'd');
|
||||
fail_unless_equals_int (editlist_mp4[28 + 6], 'a');
|
||||
fail_unless_equals_int (editlist_mp4[28 + 7], 't');
|
||||
|
||||
pipe = gst_parse_launch ("dataurisrc name=src ! qtdemux name=d "
|
||||
"d.video_0 ! appsink name=sink", NULL);
|
||||
|
||||
fail_unless (pipe != NULL);
|
||||
|
||||
src = gst_bin_get_by_name (GST_BIN (pipe), "src");
|
||||
fail_unless (src != NULL);
|
||||
|
||||
sink = gst_bin_get_by_name (GST_BIN (pipe), "sink");
|
||||
fail_unless (sink != NULL);
|
||||
|
||||
/* Convert to data: URI so we can use dataurisrc. Bit silly of course,
|
||||
* should have a memsrc or somesuch, but does the job for now */
|
||||
{
|
||||
gsize s_alloc_len = 32 + (editlist_mp4_size / 3 + 1) * 4 + 4;
|
||||
gchar *s = g_malloc0 (s_alloc_len);
|
||||
gsize s_len = 0;
|
||||
gsize base64_size;
|
||||
gint state = 0;
|
||||
gint save = 0;
|
||||
|
||||
s_len = g_strlcat (s, "data:video/quicktime;base64,", s_alloc_len);
|
||||
|
||||
base64_size =
|
||||
g_base64_encode_step (editlist_mp4, editlist_mp4_size, FALSE, s + s_len,
|
||||
&state, &save);
|
||||
s_len += base64_size;
|
||||
base64_size = g_base64_encode_close (FALSE, s + s_len, &state, &save);
|
||||
s_len += base64_size;
|
||||
g_clear_pointer (&editlist_mp4, (GDestroyNotify) g_free);
|
||||
|
||||
{
|
||||
GValue v = G_VALUE_INIT;
|
||||
|
||||
/* Avoids at least one of the two string copies */
|
||||
g_value_init (&v, G_TYPE_STRING);
|
||||
g_value_take_string (&v, s);
|
||||
g_object_set_property (G_OBJECT (src), "uri", &v);
|
||||
g_value_reset (&v);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_set (sink, "sync", FALSE, NULL);
|
||||
|
||||
gst_element_set_state (pipe, GST_STATE_PLAYING);
|
||||
|
||||
/* wait for preroll */
|
||||
{
|
||||
GstMessage *msg;
|
||||
|
||||
GST_LOG ("waiting for preroll");
|
||||
msg =
|
||||
gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipe), -1,
|
||||
GST_MESSAGE_ASYNC_DONE);
|
||||
|
||||
gst_message_unref (msg);
|
||||
}
|
||||
|
||||
/* pull video frames out of qtdemux */
|
||||
while ((sample = gst_app_sink_pull_sample (GST_APP_SINK (sink)))) {
|
||||
++frame_count;
|
||||
gst_sample_unref (sample);
|
||||
}
|
||||
|
||||
fail_unless_equals_int (frame_count, 361);
|
||||
|
||||
gst_element_set_state (pipe, GST_STATE_NULL);
|
||||
|
||||
gst_clear_object (&src);
|
||||
gst_clear_object (&sink);
|
||||
gst_clear_object (&pipe);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
qtdemux_suite (void)
|
||||
{
|
||||
|
@ -901,6 +1039,7 @@ qtdemux_suite (void)
|
|||
tcase_add_test (tc_chain, test_qtdemux_duplicated_moov);
|
||||
tcase_add_test (tc_chain, test_qtdemux_stream_change);
|
||||
tcase_add_test (tc_chain, test_qtdemux_pad_names);
|
||||
tcase_add_test (tc_chain, test_qtdemux_editlist);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
BIN
subprojects/gst-plugins-good/tests/files/editlists.mp4.gz.gz
Normal file
BIN
subprojects/gst-plugins-good/tests/files/editlists.mp4.gz.gz
Normal file
Binary file not shown.
Loading…
Reference in a new issue