Exemplo n.º 1
0
/**
 * gst_sample_get_info:
 * @sample: a #GstSample
 *
 * Get extra information associated with @sample.
 *
 * Returns: (transfer none): the extra info of @sample.
 *  The info remains valid as long as @sample is valid.
 */
const GstStructure *
gst_sample_get_info (GstSample * sample)
{
  g_return_val_if_fail (GST_IS_SAMPLE (sample), NULL);

  return sample->info;
}
Exemplo n.º 2
0
/**
 * gst_sample_get_caps:
 * @sample: a #GstSample
 *
 * Get the caps associated with @sample
 *
 * Returns: (transfer none): the caps of @sample or NULL when there
 *  is no caps. The caps remain valid as long as @sample is valid.
 */
GstCaps *
gst_sample_get_caps (GstSample * sample)
{
  g_return_val_if_fail (GST_IS_SAMPLE (sample), NULL);

  return sample->caps;
}
Exemplo n.º 3
0
/**
 * gst_sample_get_segment:
 * @sample: a #GstSample
 *
 * Get the segment associated with @sample
 *
 * Returns: (transfer none): the segment of @sample.
 *  The segment remains valid as long as @sample is valid.
 */
GstSegment *
gst_sample_get_segment (GstSample * sample)
{
  g_return_val_if_fail (GST_IS_SAMPLE (sample), NULL);

  return &sample->segment;
}
Exemplo n.º 4
0
/**
 * gst_sample_get_buffer:
 * @sample: a #GstSample
 *
 * Get the buffer associated with @sample
 *
 * Returns: (transfer none): the buffer of @sample or NULL when there
 *  is no buffer. The buffer remains valid as long as @sample is valid.
 */
GstBuffer *
gst_sample_get_buffer (GstSample * sample)
{
  g_return_val_if_fail (GST_IS_SAMPLE (sample), NULL);

  return sample->buffer;
}
PassRefPtr<BitmapTexture> MediaPlayerPrivateGStreamerBase::updateTexture(TextureMapper* textureMapper)
{
    WTF::GMutexLocker<GMutex> lock(m_sampleMutex);
    if (!GST_IS_SAMPLE(m_sample.get()))
        return nullptr;

    GstCaps* caps = gst_sample_get_caps(m_sample.get());
    if (!caps)
        return nullptr;

    GstVideoInfo videoInfo;
    gst_video_info_init(&videoInfo);
    if (!gst_video_info_from_caps(&videoInfo, caps))
        return nullptr;

    IntSize size = IntSize(GST_VIDEO_INFO_WIDTH(&videoInfo), GST_VIDEO_INFO_HEIGHT(&videoInfo));
    RefPtr<BitmapTexture> texture = textureMapper->acquireTextureFromPool(size, GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? BitmapTexture::SupportsAlpha : BitmapTexture::NoFlag);
    GstBuffer* buffer = gst_sample_get_buffer(m_sample.get());

#if GST_CHECK_VERSION(1, 1, 0)
    GstVideoGLTextureUploadMeta* meta;
    if ((meta = gst_buffer_get_video_gl_texture_upload_meta(buffer))) {
        if (meta->n_textures == 1) { // BRGx & BGRA formats use only one texture.
            const BitmapTextureGL* textureGL = static_cast<const BitmapTextureGL*>(texture.get());
            guint ids[4] = { textureGL->id(), 0, 0, 0 };

            if (gst_video_gl_texture_upload_meta_upload(meta, ids))
                return texture;
        }
    }
#endif

    // Right now the TextureMapper only supports chromas with one plane
    ASSERT(GST_VIDEO_INFO_N_PLANES(&videoInfo) == 1);

    GstVideoFrame videoFrame;
    if (!gst_video_frame_map(&videoFrame, &videoInfo, buffer, GST_MAP_READ))
        return nullptr;

    int stride = GST_VIDEO_FRAME_PLANE_STRIDE(&videoFrame, 0);
    const void* srcData = GST_VIDEO_FRAME_PLANE_DATA(&videoFrame, 0);
    texture->updateContents(srcData, WebCore::IntRect(WebCore::IntPoint(0, 0), size), WebCore::IntPoint(0, 0), stride, BitmapTexture::UpdateCannotModifyOriginalImageData);
    gst_video_frame_unmap(&videoFrame);

    return texture;
}
Exemplo n.º 6
0
// FIXME: Use gst_app_src_push_sample() instead when we switch to the appropriate GStreamer version.
static GstFlowReturn pushSample(GstAppSrc* appsrc, GstSample* sample)
{
    g_return_val_if_fail(GST_IS_SAMPLE(sample), GST_FLOW_ERROR);

    GstCaps* caps = gst_sample_get_caps(sample);
    if (caps)
        gst_app_src_set_caps(appsrc, caps);
    else
        GST_WARNING_OBJECT(appsrc, "received sample without caps");

    GstBuffer* buffer = gst_sample_get_buffer(sample);
    if (UNLIKELY(!buffer)) {
        GST_WARNING_OBJECT(appsrc, "received sample without buffer");
        return GST_FLOW_OK;
    }

    // gst_app_src_push_buffer() steals the reference, we need an additional one.
    return gst_app_src_push_buffer(appsrc, gst_buffer_ref(buffer));
}
void MediaPlayerPrivateGStreamerBase::triggerRepaint(GstSample* sample)
{
    g_return_if_fail(GST_IS_SAMPLE(sample));

    {
        GMutexLocker<GMutex> lock(m_sampleMutex);
        if (m_sample)
            gst_sample_unref(m_sample);
        m_sample = gst_sample_ref(sample);
    }

#if USE(TEXTURE_MAPPER_GL) && !USE(COORDINATED_GRAPHICS)
    if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player) && client()) {
        client()->setPlatformLayerNeedsDisplay();
        return;
    }
#endif

    m_player->repaint();
}
void MediaPlayerPrivateGStreamerBase::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
{
    if (!m_player->visible())
        return;

    if (m_usingFallbackVideoSink) {
        if (RefPtr<BitmapTexture> texture = updateTexture(textureMapper))
            textureMapper->drawTexture(*texture.get(), targetRect, matrix, opacity);
        return;
    }

#if USE(GSTREAMER_GL)
    if (!GST_IS_SAMPLE(m_sample.get()))
        return;

    GstCaps* caps = gst_sample_get_caps(m_sample.get());
    if (!caps)
        return;

    GstVideoInfo videoInfo;
    gst_video_info_init(&videoInfo);
    if (!gst_video_info_from_caps(&videoInfo, caps))
        return;

    GstBuffer* buffer = gst_sample_get_buffer(m_sample.get());
    GstVideoFrame videoFrame;
    if (!gst_video_frame_map(&videoFrame, &videoInfo, buffer, static_cast<GstMapFlags>(GST_MAP_READ | GST_MAP_GL)))
        return;

    unsigned textureID = *reinterpret_cast<unsigned*>(videoFrame.data[0]);
    BitmapTexture::Flags flags = BitmapTexture::NoFlag;
    if (GST_VIDEO_INFO_HAS_ALPHA(&videoInfo))
        flags |= BitmapTexture::SupportsAlpha;

    IntSize size = IntSize(GST_VIDEO_INFO_WIDTH(&videoInfo), GST_VIDEO_INFO_HEIGHT(&videoInfo));
    TextureMapperGL* textureMapperGL = reinterpret_cast<TextureMapperGL*>(textureMapper);
    textureMapperGL->drawTexture(textureID, flags, size, targetRect, matrix, opacity);
    gst_video_frame_unmap(&videoFrame);
#endif
}
void MediaPlayerPrivateGStreamerBase::paint(GraphicsContext& context, const FloatRect& rect)
{
#if USE(TEXTURE_MAPPER_GL) && !USE(COORDINATED_GRAPHICS)
    if (client())
        return;
#endif

    if (context.paintingDisabled())
        return;

    if (!m_player->visible())
        return;

    WTF::GMutexLocker<GMutex> lock(m_sampleMutex);
    if (!GST_IS_SAMPLE(m_sample.get()))
        return;

    RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_sample.get());
    if (!gstImage)
        return;

    if (Image* image = reinterpret_cast<Image*>(gstImage->image().get()))
        context.drawImage(*image, ColorSpaceSRGB, rect, gstImage->rect(), CompositeCopy);
}
// Returns the size of the video
FloatSize MediaPlayerPrivateGStreamerBase::naturalSize() const
{
    if (!hasVideo())
        return FloatSize();

    if (!m_videoSize.isEmpty())
        return m_videoSize;

    WTF::GMutexLocker<GMutex> lock(m_sampleMutex);
    if (!GST_IS_SAMPLE(m_sample.get()))
        return FloatSize();

    GstCaps* caps = gst_sample_get_caps(m_sample.get());
    if (!caps)
        return FloatSize();


    // TODO: handle possible clean aperture data. See
    // https://bugzilla.gnome.org/show_bug.cgi?id=596571
    // TODO: handle possible transformation matrix. See
    // https://bugzilla.gnome.org/show_bug.cgi?id=596326

    // Get the video PAR and original size, if this fails the
    // video-sink has likely not yet negotiated its caps.
    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
    IntSize originalSize;
    GstVideoFormat format;
    if (!getVideoSizeAndFormatFromCaps(caps, originalSize, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride))
        return FloatSize();

    LOG_MEDIA_MESSAGE("Original video size: %dx%d", originalSize.width(), originalSize.height());
    LOG_MEDIA_MESSAGE("Pixel aspect ratio: %d/%d", pixelAspectRatioNumerator, pixelAspectRatioDenominator);

    // Calculate DAR based on PAR and video size.
    int displayWidth = originalSize.width() * pixelAspectRatioNumerator;
    int displayHeight = originalSize.height() * pixelAspectRatioDenominator;

    // Divide display width and height by their GCD to avoid possible overflows.
    int displayAspectRatioGCD = greatestCommonDivisor(displayWidth, displayHeight);
    displayWidth /= displayAspectRatioGCD;
    displayHeight /= displayAspectRatioGCD;

    // Apply DAR to original video size. This is the same behavior as in xvimagesink's setcaps function.
    guint64 width = 0, height = 0;
    if (!(originalSize.height() % displayHeight)) {
        LOG_MEDIA_MESSAGE("Keeping video original height");
        width = gst_util_uint64_scale_int(originalSize.height(), displayWidth, displayHeight);
        height = static_cast<guint64>(originalSize.height());
    } else if (!(originalSize.width() % displayWidth)) {
        LOG_MEDIA_MESSAGE("Keeping video original width");
        height = gst_util_uint64_scale_int(originalSize.width(), displayHeight, displayWidth);
        width = static_cast<guint64>(originalSize.width());
    } else {
        LOG_MEDIA_MESSAGE("Approximating while keeping original video height");
        width = gst_util_uint64_scale_int(originalSize.height(), displayWidth, displayHeight);
        height = static_cast<guint64>(originalSize.height());
    }

    LOG_MEDIA_MESSAGE("Natural size: %" G_GUINT64_FORMAT "x%" G_GUINT64_FORMAT, width, height);
    m_videoSize = FloatSize(static_cast<int>(width), static_cast<int>(height));
    return m_videoSize;
}
Exemplo n.º 11
0
extern GstFlowReturn
on_appsink_new_sample (GstElement * element, GNUNET_gstData * d)
{
  static unsigned long long toff;

  //size of message including gnunet header
  size_t msg_size;

  GstSample *s;
  GstBuffer *b;
  GstMapInfo map;
/*
  const GstStructure *si;
  char *si_str;
  GstCaps *s_caps;
  char *caps_str;
*/
  (d->audio_message)->header.size = htons ((uint16_t) msg_size);

  if (gst_app_sink_is_eos(GST_APP_SINK(element)))
    return GST_FLOW_OK;

  //pull sample from appsink
   s = gst_app_sink_pull_sample (GST_APP_SINK(element));

   if (s == NULL)
     return GST_FLOW_OK;

   if (!GST_IS_SAMPLE (s))
     return GST_FLOW_OK;

   b = gst_sample_get_buffer(s);

   GST_WARNING ("caps are %" GST_PTR_FORMAT, gst_sample_get_caps(s));



   gst_buffer_map (b, &map, GST_MAP_READ);

   size_t len;
    len = map.size;
   if (len > UINT16_MAX - sizeof (struct AudioMessage))
   {
     // this should never happen?
     printf("GSTREAMER sample too big! \n");
     exit(20);
     len = UINT16_MAX - sizeof (struct AudioMessage);
   }

   msg_size = sizeof (struct AudioMessage) + len;

  // copy the data into audio_message
  GNUNET_memcpy (((char *) &(d->audio_message)[1]), map.data, len);
/*
  toff += msg_size;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending %u bytes of audio data (total: %llu)\n",
              (unsigned int) msg_size,
              toff);
*/
  if (d->pure_ogg)
    // write the audio_message without the gnunet headers
    write_data ((const char *) &(d->audio_message)[1], len);
  else
    write_data ((const char *) d->audio_message, msg_size);

   gst_sample_unref(s);
  return GST_FLOW_OK;
}
Exemplo n.º 12
0
static void
run_decoding_test (GstElement * mpg123audiodec, gchar const *filename)
{
  GstBus *bus;
  unsigned int num_input_buffers, num_decoded_buffers;
  gint expected_size;
  GstCaps *out_caps, *caps;
  GstAudioInfo audioinfo;
  GstElement *input_pipeline, *input_appsink;
  int i;
  GstBuffer *outbuffer;

  /* 440 Hz = frequency of sine wave in audio data
   * 44100 Hz = sample rate
   * (44100 / 2) Hz = Nyquist frequency */
  static double const expected_frequency_spot = 440.0 / (44100.0 / 2.0);

  fail_unless (gst_element_set_state (mpg123audiodec,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
      "could not set to playing");
  bus = gst_bus_new ();

  gst_element_set_bus (mpg123audiodec, bus);

  setup_input_pipeline (filename, &input_pipeline, &input_appsink);

  num_input_buffers = 0;
  while (TRUE) {
    GstSample *sample;
    GstBuffer *input_buffer;

    sample = gst_app_sink_pull_sample (GST_APP_SINK (input_appsink));
    if (sample == NULL)
      break;

    fail_unless (GST_IS_SAMPLE (sample));

    input_buffer = gst_sample_get_buffer (sample);
    fail_if (input_buffer == NULL);

    /* This is done to be on the safe side - docs say lifetime of the input buffer
     * depends *solely* on the sample */
    input_buffer = gst_buffer_copy (input_buffer);

    fail_unless_equals_int (gst_pad_push (mysrcpad, input_buffer), GST_FLOW_OK);

    ++num_input_buffers;

    gst_sample_unref (sample);
  }

  num_decoded_buffers = g_list_length (buffers);

  /* check number of decoded buffers */
  fail_unless_equals_int (num_decoded_buffers, num_input_buffers - 2);

  caps = gst_pad_get_current_caps (mysinkpad);
  GST_LOG ("output caps %" GST_PTR_FORMAT, caps);
  fail_unless (gst_audio_info_from_caps (&audioinfo, caps),
      "Getting audio info from caps failed");

  /* check caps */
  out_caps = gst_caps_new_simple ("audio/x-raw",
      "format", G_TYPE_STRING, "S32LE",
      "layout", G_TYPE_STRING, "interleaved",
      "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL);

  fail_unless (gst_caps_is_equal_fixed (caps, out_caps), "Incorrect out caps");

  gst_caps_unref (out_caps);
  gst_caps_unref (caps);

  /* here, test if decoded data is a sine tone, and if the sine frequency is at the
   * right spot in the spectrum */
  for (i = 0; i < num_decoded_buffers; ++i) {
    outbuffer = GST_BUFFER (buffers->data);
    fail_if (outbuffer == NULL, "Invalid buffer retrieved");

    /* MPEG 1 layer 2 uses 1152 samples per frame */
    expected_size = 1152 * GST_AUDIO_INFO_BPF (&audioinfo);
    fail_unless_equals_int (gst_buffer_get_size (outbuffer), expected_size);

    check_main_frequency_spot_S32 (outbuffer, expected_frequency_spot);

    buffers = g_list_remove (buffers, outbuffer);
    gst_buffer_unref (outbuffer);
    outbuffer = NULL;
  }

  g_list_free (buffers);
  buffers = NULL;

  cleanup_input_pipeline (input_pipeline);
  gst_bus_set_flushing (bus, TRUE);
  gst_element_set_bus (mpg123audiodec, NULL);
  gst_object_unref (GST_OBJECT (bus));
}