void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info) { if (G_UNLIKELY (info)) { window->video_width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); window->video_height = info->height; wl_subsurface_set_sync (window->video_subsurface); gst_wl_window_resize_video_surface (window, FALSE); gst_wl_window_set_opaque (window, info); } if (G_LIKELY (buffer)) gst_wl_buffer_attach (buffer, window->video_surface_wrapper); else wl_surface_attach (window->video_surface_wrapper, NULL, 0, 0); wl_surface_damage (window->video_surface_wrapper, 0, 0, window->video_rectangle.w, window->video_rectangle.h); wl_surface_commit (window->video_surface_wrapper); if (G_UNLIKELY (info)) { /* commit also the parent (area_surface) in order to change * the position of the video_subsurface */ wl_surface_damage (window->area_surface_wrapper, 0, 0, window->render_rectangle.w, window->render_rectangle.h); wl_surface_commit (window->area_surface_wrapper); wl_subsurface_set_desync (window->video_subsurface); } wl_display_flush (window->display->display); }
GstWlWindow * gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info) { GstWlWindow *window; gint width; window = gst_wl_window_new_internal (display); /* go toplevel */ window->shell_surface = wl_shell_get_shell_surface (display->shell, window->area_surface); if (window->shell_surface) { wl_shell_surface_add_listener (window->shell_surface, &shell_surface_listener, window); wl_shell_surface_set_toplevel (window->shell_surface); } else { GST_ERROR ("Unable to get wl_shell_surface"); g_object_unref (window); return NULL; } /* set the initial size to be the same as the reported video size */ width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); return window; }
void gst_wl_window_set_video_info (GstWlWindow * window, GstVideoInfo * info) { g_return_if_fail (window != NULL); window->video_width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); window->video_height = info->height; if (window->render_rectangle.w != 0) gst_wl_window_resize_internal (window, FALSE); }
gboolean ks_video_fixate_media_type (const KSDATARANGE * range, guint8 * format, gint width, gint height, gint fps_n, gint fps_d) { KS_DATARANGE_VIDEO *vr; KS_VIDEOINFOHEADER *vih; KS_BITMAPINFOHEADER *bih; DWORD dwRate; g_return_val_if_fail (format != NULL, FALSE); if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo)) { bih = &((KS_VIDEOINFOHEADER *) format)->bmiHeader; } else if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo2)) { bih = &((KS_VIDEOINFOHEADER2 *) format)->bmiHeader; } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEGVideo)) { bih = &((KS_MPEG1VIDEOINFO *) format)->hdr.bmiHeader; } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) { bih = &((KS_MPEGVIDEOINFO2 *) format)->hdr.bmiHeader; } else { return FALSE; } /* These formats' structures share the most basic stuff */ vr = (KS_DATARANGE_VIDEO *) range; vih = (KS_VIDEOINFOHEADER *) format; /* FIXME: Need to figure out how to properly handle ranges */ if (bih->biWidth != width || bih->biHeight != height) return FALSE; /* Framerate, clamped because of fraction conversion rounding errors */ vih->AvgTimePerFrame = gst_util_uint64_scale_int_round (NANOSECONDS, fps_d, fps_n); vih->AvgTimePerFrame = MAX (vih->AvgTimePerFrame, vr->ConfigCaps.MinFrameInterval); vih->AvgTimePerFrame = MIN (vih->AvgTimePerFrame, vr->ConfigCaps.MaxFrameInterval); /* Bitrate, clamped for the same reason as framerate */ dwRate = (width * height * fps_n) / fps_d; vih->dwBitRate = dwRate * bih->biBitCount; vih->dwBitRate = MAX (vih->dwBitRate, vr->ConfigCaps.MinBitsPerSecond); vih->dwBitRate = MIN (vih->dwBitRate, vr->ConfigCaps.MaxBitsPerSecond); return TRUE; }
GstWlWindow * gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock) { GstWlWindow *window; gint width; window = gst_wl_window_new_internal (display, render_lock); if (display->shell) { /* go toplevel */ window->shell_surface = wl_shell_get_shell_surface (display->shell, window->area_surface); if (window->shell_surface) { wl_shell_surface_add_listener (window->shell_surface, &shell_surface_listener, window); gst_wl_window_ensure_fullscreen (window, fullscreen); } else { GST_ERROR ("Unable to get wl_shell_surface"); g_object_unref (window); return NULL; } } else if (display->fullscreen_shell) { zwp_fullscreen_shell_v1_present_surface (display->fullscreen_shell, window->area_surface, ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_ZOOM, NULL); } else { GST_ERROR ("Unable to use wl_shell or zwp_fullscreen_shell."); g_object_unref (window); return NULL; } /* set the initial size to be the same as the reported video size */ width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); return window; }
GstIsoffParserResult gst_isoff_sidx_parser_parse (GstSidxParser * parser, GstByteReader * reader, guint * consumed) { GstIsoffParserResult res = GST_ISOFF_PARSER_OK; gsize remaining; switch (parser->status) { case GST_ISOFF_SIDX_PARSER_INIT: /* Try again once we have enough data for the FullBox header */ if (gst_byte_reader_get_remaining (reader) < 4) { gst_byte_reader_set_pos (reader, 0); break; } parser->sidx.version = gst_byte_reader_get_uint8_unchecked (reader); parser->sidx.flags = gst_byte_reader_get_uint24_le_unchecked (reader); parser->status = GST_ISOFF_SIDX_PARSER_HEADER; case GST_ISOFF_SIDX_PARSER_HEADER: remaining = gst_byte_reader_get_remaining (reader); if (remaining < 12 + (parser->sidx.version == 0 ? 8 : 16)) { break; } parser->sidx.ref_id = gst_byte_reader_get_uint32_be_unchecked (reader); parser->sidx.timescale = gst_byte_reader_get_uint32_be_unchecked (reader); if (parser->sidx.version == 0) { parser->sidx.earliest_pts = gst_byte_reader_get_uint32_be_unchecked (reader); parser->sidx.first_offset = gst_byte_reader_get_uint32_be_unchecked (reader); } else { parser->sidx.earliest_pts = gst_byte_reader_get_uint64_be_unchecked (reader); parser->sidx.first_offset = gst_byte_reader_get_uint64_be_unchecked (reader); } /* skip 2 reserved bytes */ gst_byte_reader_skip_unchecked (reader, 2); parser->sidx.entries_count = gst_byte_reader_get_uint16_be_unchecked (reader); GST_LOG ("Timescale: %" G_GUINT32_FORMAT, parser->sidx.timescale); GST_LOG ("Earliest pts: %" G_GUINT64_FORMAT, parser->sidx.earliest_pts); GST_LOG ("First offset: %" G_GUINT64_FORMAT, parser->sidx.first_offset); parser->cumulative_pts = gst_util_uint64_scale_int_round (parser->sidx.earliest_pts, GST_SECOND, parser->sidx.timescale); if (parser->sidx.entries_count) { parser->sidx.entries = g_malloc (sizeof (GstSidxBoxEntry) * parser->sidx.entries_count); } parser->sidx.entry_index = 0; parser->status = GST_ISOFF_SIDX_PARSER_DATA; case GST_ISOFF_SIDX_PARSER_DATA: while (parser->sidx.entry_index < parser->sidx.entries_count) { GstSidxBoxEntry *entry = &parser->sidx.entries[parser->sidx.entry_index]; remaining = gst_byte_reader_get_remaining (reader); if (remaining < 12) break; entry->offset = parser->cumulative_entry_size; entry->pts = parser->cumulative_pts; gst_isoff_parse_sidx_entry (entry, reader); entry->duration = gst_util_uint64_scale_int_round (entry->duration, GST_SECOND, parser->sidx.timescale); parser->cumulative_entry_size += entry->size; parser->cumulative_pts += entry->duration; GST_LOG ("Sidx entry %d) offset: %" G_GUINT64_FORMAT ", pts: %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT " - size %" G_GUINT32_FORMAT, parser->sidx.entry_index, entry->offset, GST_TIME_ARGS (entry->pts), GST_TIME_ARGS (entry->duration), entry->size); parser->sidx.entry_index++; } if (parser->sidx.entry_index == parser->sidx.entries_count) parser->status = GST_ISOFF_SIDX_PARSER_FINISHED; else break; case GST_ISOFF_SIDX_PARSER_FINISHED: parser->sidx.entry_index = 0; res = GST_ISOFF_PARSER_DONE; break; } *consumed = gst_byte_reader_get_pos (reader); return res; }
static gboolean gst_audio_test_src_query (GstBaseSrc * basesrc, GstQuery * query) { GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (basesrc); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); if (src_fmt == dest_fmt) { dest_val = src_val; goto done; } switch (src_fmt) { case GST_FORMAT_DEFAULT: switch (dest_fmt) { case GST_FORMAT_TIME: /* samples to time */ dest_val = gst_util_uint64_scale_int (src_val, GST_SECOND, src->samplerate); break; default: goto error; } break; case GST_FORMAT_TIME: switch (dest_fmt) { case GST_FORMAT_DEFAULT: /* time to samples */ dest_val = gst_util_uint64_scale_int_round (src_val, src->samplerate, GST_SECOND); break; default: goto error; } break; default: goto error; } done: gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); break; } return res; /* ERROR */ error: { GST_DEBUG_OBJECT (src, "query failed"); return FALSE; } }
GstIsoffParserResult gst_isoff_sidx_parser_add_buffer (GstSidxParser * parser, GstBuffer * buffer, guint * consumed) { GstIsoffParserResult res = GST_ISOFF_PARSER_OK; GstByteReader reader; GstMapInfo info; gsize remaining; guint32 fourcc; if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { *consumed = 0; return GST_ISOFF_PARSER_ERROR; } gst_byte_reader_init (&reader, info.data, info.size); switch (parser->status) { case GST_ISOFF_SIDX_PARSER_INIT: if (gst_byte_reader_get_remaining (&reader) < GST_ISOFF_FULL_BOX_SIZE) { break; } parser->size = gst_byte_reader_get_uint32_be_unchecked (&reader); fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader); if (fourcc != GST_ISOFF_FOURCC_SIDX) { res = GST_ISOFF_PARSER_UNEXPECTED; gst_byte_reader_set_pos (&reader, 0); break; } if (parser->size == 1) { if (gst_byte_reader_get_remaining (&reader) < 12) { gst_byte_reader_set_pos (&reader, 0); break; } parser->size = gst_byte_reader_get_uint64_be_unchecked (&reader); } if (parser->size == 0) { res = GST_ISOFF_PARSER_ERROR; gst_byte_reader_set_pos (&reader, 0); break; } parser->sidx.version = gst_byte_reader_get_uint8_unchecked (&reader); parser->sidx.flags = gst_byte_reader_get_uint24_le_unchecked (&reader); parser->status = GST_ISOFF_SIDX_PARSER_HEADER; case GST_ISOFF_SIDX_PARSER_HEADER: remaining = gst_byte_reader_get_remaining (&reader); if (remaining < 12 + (parser->sidx.version == 0 ? 8 : 16)) { break; } parser->sidx.ref_id = gst_byte_reader_get_uint32_be_unchecked (&reader); parser->sidx.timescale = gst_byte_reader_get_uint32_be_unchecked (&reader); if (parser->sidx.version == 0) { parser->sidx.earliest_pts = gst_byte_reader_get_uint32_be_unchecked (&reader); parser->sidx.first_offset = parser->sidx.earliest_pts = gst_byte_reader_get_uint32_be_unchecked (&reader); } else { parser->sidx.earliest_pts = gst_byte_reader_get_uint64_be_unchecked (&reader); parser->sidx.first_offset = gst_byte_reader_get_uint64_be_unchecked (&reader); } /* skip 2 reserved bytes */ gst_byte_reader_skip_unchecked (&reader, 2); parser->sidx.entries_count = gst_byte_reader_get_uint16_be_unchecked (&reader); GST_LOG ("Timescale: %" G_GUINT32_FORMAT, parser->sidx.timescale); GST_LOG ("Earliest pts: %" G_GUINT64_FORMAT, parser->sidx.earliest_pts); GST_LOG ("First offset: %" G_GUINT64_FORMAT, parser->sidx.first_offset); parser->cumulative_pts = gst_util_uint64_scale_int_round (parser->sidx.earliest_pts, GST_SECOND, parser->sidx.timescale); if (parser->sidx.entries_count) { parser->sidx.entries = g_malloc (sizeof (GstSidxBoxEntry) * parser->sidx.entries_count); } parser->sidx.entry_index = 0; parser->status = GST_ISOFF_SIDX_PARSER_DATA; case GST_ISOFF_SIDX_PARSER_DATA: while (parser->sidx.entry_index < parser->sidx.entries_count) { GstSidxBoxEntry *entry = &parser->sidx.entries[parser->sidx.entry_index]; remaining = gst_byte_reader_get_remaining (&reader);; if (remaining < 12) break; entry->offset = parser->cumulative_entry_size; entry->pts = parser->cumulative_pts; gst_isoff_parse_sidx_entry (entry, &reader); entry->duration = gst_util_uint64_scale_int_round (entry->duration, GST_SECOND, parser->sidx.timescale); parser->cumulative_entry_size += entry->size; parser->cumulative_pts += entry->duration; GST_LOG ("Sidx entry %d) offset: %" G_GUINT64_FORMAT ", pts: %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT " - size %" G_GUINT32_FORMAT, parser->sidx.entry_index, entry->offset, GST_TIME_ARGS (entry->pts), GST_TIME_ARGS (entry->duration), entry->size); parser->sidx.entry_index++; } if (parser->sidx.entry_index == parser->sidx.entries_count) parser->status = GST_ISOFF_SIDX_PARSER_FINISHED; else break; case GST_ISOFF_SIDX_PARSER_FINISHED: parser->sidx.entry_index = 0; res = GST_ISOFF_PARSER_DONE; break; } *consumed = gst_byte_reader_get_pos (&reader); gst_buffer_unmap (buffer, &info); return res; }