parse-test.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include <gst/gst.h>
  2. #include <string.h>
  3. #include <stdbool.h>
  4. #include "gstdspparse.h"
  5. #include "gstdspvdec.h"
  6. typedef bool (*parse_func)(GstDspBase *base, GstBuffer *buf);
  7. static char *filename;
  8. static char *result;
  9. static char *result_crop;
  10. static GMainLoop *loop;
  11. static GstElement *pipeline;
  12. static GstElement *src, *demux, *sink;
  13. static GstDspBase *dec;
  14. static parse_func gst_dsp_parse;
  15. static unsigned buffer_count;
  16. static gboolean bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
  17. {
  18. switch (GST_MESSAGE_TYPE(msg)) {
  19. case GST_MESSAGE_EOS:
  20. g_main_loop_quit(loop);
  21. break;
  22. case GST_MESSAGE_ERROR: {
  23. gchar *debug;
  24. GError *err;
  25. gst_message_parse_error(msg, &err, &debug);
  26. g_printerr("error: %s: %s\n", err->message, debug);
  27. g_error_free(err);
  28. g_free(debug);
  29. g_main_loop_quit(loop);
  30. break;
  31. }
  32. default:
  33. break;
  34. }
  35. return TRUE;
  36. }
  37. static void on_pad_added(GstElement *element, GstPad *pad, gpointer data)
  38. {
  39. GstPad *sinkpad;
  40. GstStructure *struc;
  41. const gchar *name;
  42. sinkpad = gst_element_get_static_pad(sink, "sink");
  43. gst_pad_link(pad, sinkpad);
  44. gst_object_unref(sinkpad);
  45. struc = gst_caps_get_structure(GST_PAD_CAPS(pad), 0);
  46. name = gst_structure_get_name(struc);
  47. if (strncmp(name, "video/", 6) != 0)
  48. return;
  49. if (strcmp(name, "video/x-h263") == 0)
  50. gst_dsp_parse = gst_dsp_h263_parse;
  51. else if (strcmp(name, "video/x-h264") == 0)
  52. gst_dsp_parse = gst_dsp_h264_parse;
  53. else
  54. gst_dsp_parse = gst_dsp_mpeg4_parse;
  55. }
  56. static void handoff(GstElement *object,
  57. GstBuffer *buffer,
  58. GstPad *pad,
  59. gpointer user_data)
  60. {
  61. GstStructure *struc;
  62. const GValue *codec_data;
  63. bool r;
  64. buffer_count++;
  65. struc = gst_caps_get_structure(GST_BUFFER_CAPS(buffer), 0);
  66. codec_data = gst_structure_get_value(struc, "codec_data");
  67. if (codec_data) {
  68. GstBuffer *tmp;
  69. tmp = gst_value_get_buffer(codec_data);
  70. r = gst_dsp_parse(dec, tmp);
  71. if (r)
  72. goto ok;
  73. else
  74. g_printerr("bad codec data\n");
  75. }
  76. r = gst_dsp_parse(dec, buffer);
  77. ok:
  78. if (r) {
  79. GstDspVDec *vdec = GST_DSP_VDEC(dec);
  80. result = g_strdup_printf("fs=%ix%i",
  81. vdec->width, vdec->height);
  82. result_crop = g_strdup_printf("cfs=%ix%i",
  83. vdec->crop_width, vdec->crop_height);
  84. } else {
  85. g_printerr("parse error\n");
  86. }
  87. g_main_loop_quit(loop);
  88. }
  89. static void init(void)
  90. {
  91. pipeline = gst_pipeline_new("parse");
  92. src = gst_element_factory_make("filesrc", "src");
  93. demux = gst_element_factory_make("qtdemux", "demux");
  94. sink = gst_element_factory_make("fakesink", "sink");
  95. gst_bin_add_many(GST_BIN(pipeline), src, demux, sink, NULL);
  96. gst_element_link(src, demux);
  97. g_signal_connect(demux, "pad-added", G_CALLBACK(on_pad_added), NULL);
  98. GstBus *bus;
  99. bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
  100. gst_bus_add_watch(bus, bus_cb, NULL);
  101. gst_object_unref(bus);
  102. g_object_set(G_OBJECT(src), "location", filename, NULL);
  103. g_object_set(G_OBJECT(sink), "signal-handoffs", TRUE, "num-buffers", 1, NULL);
  104. g_signal_connect(sink, "handoff", G_CALLBACK(handoff), NULL);
  105. gst_element_set_state(pipeline, GST_STATE_PLAYING);
  106. }
  107. GstDebugCategory *gstdsp_debug;
  108. int main(int argc, char *argv[])
  109. {
  110. int ret;
  111. char *expected;
  112. char *expected_crop = NULL;
  113. gst_init(&argc, &argv);
  114. loop = g_main_loop_new(NULL, FALSE);
  115. if (argc < 3)
  116. return -1;
  117. filename = argv[1];
  118. expected = argv[2];
  119. if (argc >= 4)
  120. expected_crop = argv[3];
  121. #ifndef GST_DISABLE_GST_DEBUG
  122. gstdsp_debug = _gst_debug_category_new("dsp", 0, "DSP stuff");
  123. #endif
  124. dec = g_object_new(GST_DSP_VDEC_TYPE, NULL);
  125. init();
  126. g_main_loop_run(loop);
  127. if (result) {
  128. g_print("%s %s\n", result, result_crop);
  129. } else {
  130. if (buffer_count == 0)
  131. g_printerr("no data\n");
  132. else
  133. g_printerr("no result\n");
  134. }
  135. ret = !!g_strcmp0(expected, result);
  136. if (!ret && expected_crop)
  137. ret = !!g_strcmp0(expected_crop, result_crop);
  138. g_free(result);
  139. g_free(result_crop);
  140. if (pipeline) {
  141. gst_element_set_state(pipeline, GST_STATE_NULL);
  142. gst_object_unref(GST_OBJECT(pipeline));
  143. }
  144. g_object_unref(dec);
  145. g_main_loop_unref(loop);
  146. return -ret;
  147. }