コード例 #1
0
ファイル: gstadapter.c プロジェクト: kkonopko/gstreamer
/**
 * gst_adapter_push:
 * @adapter: a #GstAdapter
 * @buf: (transfer full): a #GstBuffer to add to queue in the adapter
 *
 * Adds the data from @buf to the data stored inside @adapter and takes
 * ownership of the buffer.
 */
void
gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
{
  gsize size;

  g_return_if_fail (GST_IS_ADAPTER (adapter));
  g_return_if_fail (GST_IS_BUFFER (buf));

  size = gst_buffer_get_size (buf);
  adapter->size += size;

  /* Note: merging buffers at this point is premature. */
  if (G_UNLIKELY (adapter->buflist == NULL)) {
    GST_LOG_OBJECT (adapter, "pushing %p first %" G_GSIZE_FORMAT " bytes",
        buf, size);
    adapter->buflist = adapter->buflist_end = g_slist_append (NULL, buf);
    update_timestamps (adapter, buf);
  } else {
    /* Otherwise append to the end, and advance our end pointer */
    GST_LOG_OBJECT (adapter, "pushing %p %" G_GSIZE_FORMAT " bytes at end, "
        "size now %" G_GSIZE_FORMAT, buf, size, adapter->size);
    adapter->buflist_end = g_slist_append (adapter->buflist_end, buf);
    adapter->buflist_end = g_slist_next (adapter->buflist_end);
  }
}
コード例 #2
0
ファイル: gstadapter.c プロジェクト: Kurento/gstreamer
/*Flushes the first @flush bytes in the @adapter*/
static void
gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush)
{
  GstBuffer *cur;
  gsize size;
  GSList *g;

  GST_LOG_OBJECT (adapter, "flushing %" G_GSIZE_FORMAT " bytes", flush);

  if (adapter->info.memory)
    gst_adapter_unmap (adapter);

  /* clear state */
  adapter->size -= flush;
  adapter->assembled_len = 0;

  /* take skip into account */
  flush += adapter->skip;
  /* distance is always at least the amount of skipped bytes */
  adapter->pts_distance -= adapter->skip;
  adapter->dts_distance -= adapter->skip;

  g = adapter->buflist;
  cur = g->data;
  size = gst_buffer_get_size (cur);
  while (flush >= size) {
    /* can skip whole buffer */
    GST_LOG_OBJECT (adapter, "flushing out head buffer");
    adapter->pts_distance += size;
    adapter->dts_distance += size;
    flush -= size;

    gst_buffer_unref (cur);
    g = g_slist_delete_link (g, g);
    --adapter->count;

    if (G_UNLIKELY (g == NULL)) {
      GST_LOG_OBJECT (adapter, "adapter empty now");
      adapter->buflist_end = NULL;
      break;
    }
    /* there is a new head buffer, update the timestamps */
    cur = g->data;
    update_timestamps (adapter, cur);
    size = gst_buffer_get_size (cur);
  }
  adapter->buflist = g;
  /* account for the remaining bytes */
  adapter->skip = flush;
  adapter->pts_distance += flush;
  adapter->dts_distance += flush;
  /* invalidate scan position */
  adapter->scan_offset = 0;
  adapter->scan_entry = NULL;
}
コード例 #3
0
static GstFlowReturn
gst_dvdlpcmdec_chain_raw (GstPad * pad, GstBuffer * buf)
{
  GstDvdLpcmDec *dvdlpcmdec;
  guint8 *data;
  guint size;
  GstFlowReturn ret;
  guint samples = 0;

  dvdlpcmdec = GST_DVDLPCMDEC (gst_pad_get_parent (pad));

  size = GST_BUFFER_SIZE (buf);
  data = GST_BUFFER_DATA (buf);

  GST_LOG_OBJECT (dvdlpcmdec,
      "got buffer %p of size %d with ts %" GST_TIME_FORMAT,
      buf, size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

  if (dvdlpcmdec->rate == 0)
    goto not_negotiated;

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
    dvdlpcmdec->timestamp = GST_BUFFER_TIMESTAMP (buf);

  /* We don't currently do anything at all regarding emphasis, mute or
   * dynamic_range - I'm not sure what they're for */
  switch (dvdlpcmdec->width) {
    case 16:
    {
      /* We can just pass 16-bits straight through intact, once we set
       * appropriate things on the buffer */
      samples = size / dvdlpcmdec->channels / 2;
      if (samples < 1)
        goto drop;
      buf = gst_buffer_make_metadata_writable (buf);
      break;
    }
    case 20:
    {
      /* Allocate a new buffer and copy 20-bit width to 24-bit */
      gint64 samples = size * 8 / 20;
      gint64 count = size / 10;
      gint64 i;
      guint8 *src;
      guint8 *dest;
      GstBuffer *outbuf;
      GstCaps *bufcaps = GST_PAD_CAPS (dvdlpcmdec->srcpad);

      if (samples < 1)
        goto drop;

      ret = gst_pad_alloc_buffer_and_set_caps (dvdlpcmdec->srcpad, 0,
          samples * 3, bufcaps, &outbuf);

      if (ret != GST_FLOW_OK)
        goto buffer_alloc_failed;

      gst_buffer_copy_metadata (outbuf, buf, GST_BUFFER_COPY_TIMESTAMPS);

      /* adjust samples so we can calc the new timestamp */
      samples = samples / dvdlpcmdec->channels;

      src = data;
      dest = GST_BUFFER_DATA (outbuf);

      /* Copy 20-bit LPCM format to 24-bit buffers, with 0x00 in the lowest
       * nibble. Note that the first 2 bytes are already correct */
      for (i = 0; i < count; i++) {
        dest[0] = src[0];
        dest[1] = src[1];
        dest[2] = src[8] & 0xf0;
        dest[3] = src[2];
        dest[4] = src[3];
        dest[5] = (src[8] & 0x0f) << 4;
        dest[6] = src[4];
        dest[7] = src[5];
        dest[8] = src[9] & 0x0f;
        dest[9] = src[6];
        dest[10] = src[7];
        dest[11] = (src[9] & 0x0f) << 4;

        src += 10;
        dest += 12;
      }

      gst_buffer_unref (buf);
      buf = outbuf;
      break;
    }
    case 24:
    {
      /* Rearrange 24-bit LPCM format in-place. Note that the first 2
       * and last byte are already correct */
      guint count = size / 12;
      gint i;
      guint8 *src;

      samples = size / dvdlpcmdec->channels / 3;

      if (samples < 1)
        goto drop;

      /* Ensure our output buffer is writable */
      buf = gst_buffer_make_writable (buf);

      src = GST_BUFFER_DATA (buf);
      for (i = 0; i < count; i++) {
        guint8 tmp;

        tmp = src[10];
        src[10] = src[7];
        src[7] = src[5];
        src[5] = src[9];
        src[9] = src[6];
        src[6] = src[4];
        src[4] = src[3];
        src[3] = src[2];
        src[2] = src[8];
        src[8] = tmp;

        src += 12;
      }
      break;
    }
    default:
      goto invalid_width;
  }

  /* Set appropriate caps on it to pass downstream */
  gst_buffer_set_caps (buf, GST_PAD_CAPS (dvdlpcmdec->srcpad));
  update_timestamps (dvdlpcmdec, buf, samples);

  ret = gst_pad_push (dvdlpcmdec->srcpad, buf);

done:
  gst_object_unref (dvdlpcmdec);

  return ret;

  /* ERRORS */
drop:
  {
    GST_DEBUG_OBJECT (dvdlpcmdec, "Buffer of size %u is too small. Dropping",
        GST_BUFFER_SIZE (buf));
    gst_buffer_unref (buf);
    ret = GST_FLOW_OK;
    goto done;
  }
not_negotiated:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, FORMAT, (NULL),
        ("Buffer pushed before negotiation"));
    gst_buffer_unref (buf);
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
buffer_alloc_failed:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, RESOURCE, FAILED, (NULL),
        ("Buffer allocation failed"));
    gst_buffer_unref (buf);
    goto done;
  }
invalid_width:
  {
    GST_ELEMENT_ERROR (dvdlpcmdec, STREAM, WRONG_TYPE, (NULL),
        ("Invalid sample width configured"));
    gst_buffer_unref (buf);
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
}
コード例 #4
0
ファイル: mknull.c プロジェクト: MattHung/sage-graphics
int
main (int argc, char **argv)
{
	int opt, i, j, bufsize, retcode;
	int bitrate, invert, packets, packetsize, tssize, packetnum, bytes;
	unsigned char *data, *p;
	char *endptr;
	unsigned long long int timestamp, sum;

	bitrate = 0;
	invert = 0;
	packets = -1; /* Generate an infinite number of packets */
	packetsize = 188;
	while ((opt = getopt (argc, argv, "b:hin:V2")) != -1) {
		switch (opt) {
		case 'b':
			bitrate = strtol (optarg, &endptr, 0);
			if ((*endptr != '\0') ||
				(bitrate <= 0) || (bitrate > 216000000)) {
				fprintf (stderr,
					"%s: invalid bitrate: %s\n",
					argv[0], optarg);
				return -1;
			}
			break;
		case 'h':
			printf ("Usage: %s [OPTION]...\n", argv[0]);
			printf ("Repeatedly output null "
				"MPEG-2 transport stream packets\n"
				"with an ascending continuity_counter "
				"and a payload of 0xff.\n\n");
			printf ("  -b BITRATE\tprepend timestamps "
				"at BITRATE bits per second\n");
			printf ("  -h\t\tdisplay this help and exit\n");
			printf ("  -i\t\tinvert every eighth "
				"packet synchronization byte\n");
			printf ("  -n NUM\tstop after NUM packets\n");
			printf ("  -V\t\toutput version information "
				"and exit\n");
			printf ("  -2\t\tappend sixteen 0x00 bytes "
				"to each 188-byte packet\n");
			printf ("\nReport bugs to <*****@*****.**>.\n");
			return 0;
		case 'i':
			invert = 1;
			break;
		case 'n':
			packets = strtol (optarg, &endptr, 0);
			if (*endptr != '\0') {
				fprintf (stderr,
					"%s: invalid number of packets: %s\n",
					argv[0], optarg);
				return -1;
			}
			break;
		case 'V':
			printf ("%s from master-%s (%s)\n", progname,
				MASTER_DRIVER_VERSION,
				MASTER_DRIVER_DATE);
			printf ("\nCopyright (C) 2001-2006 "
				"Linear Systems Ltd.\n"
				"This is free software; "
				"see the source for copying conditions.  "
				"There is NO\n"
				"warranty; not even for MERCHANTABILITY "
				"or FITNESS FOR A PARTICULAR PURPOSE.\n");
			return 0;
		case '2':
			packetsize = 204;
			break;
		case '?':
			goto USAGE;
		}
	}

	/* Check the number of arguments */
	if ((argc - optind) > 0) {
		fprintf (stderr, "%s: extra operand\n", argv[0]);
		goto USAGE;
	}

	/* Allocate a buffer */
	tssize = (bitrate > 0) ? 8 : 0;
	bufsize = BUFFERED_PACKETS * (packetsize + tssize);
	if ((data = (unsigned char *)malloc (bufsize)) == NULL) {
		fprintf (stderr, "%s: unable to allocate memory\n", argv[0]);
		return -1;
	}

	/* Initialize the buffer */
	p = data;
	packetnum = 0;
	for (i = 0; i < BUFFERED_PACKETS; i++) {
		if (bitrate > 0) {
			p += 8;
		}
		if (invert) {
			*p++ = (packetnum % 8) ? 0x47 : 0xB8;
		} else {
			*p++ = 0x47;
		}
		*p++ = 0x1f;
		*p++ = 0xff;
		*p++ = 0x10 | packetnum;
		packetnum = (packetnum + 1) & 0x0f;
		for (j = 4; j < 188; j++) {
			*p++ = 0xff;
		}
		for (j = 188; j < packetsize; j++) {
			*p++ = 0x00;
		}
	}
	timestamp = 0ULL;
	sum = 0ULL;
	if (bitrate > 0) {
		uint64_t *ts = (uint64_t *)data;

		update_timestamps (data,
			&timestamp,
			&sum,
			bitrate,
			packetsize);
		*ts |= UINT64_C(0x8000000000000000);
	}

	/* Generate the data */
	while (packets) {
		bytes = 0;
		if ((packets < BUFFERED_PACKETS) && (packets > 0)) {
			/* The number of packets to write is less than
			 * the buffer size and is not infinite (-1). */
			while (bytes < (packets * (packetsize + tssize))) {
				if ((retcode = write (STDOUT_FILENO,
					data + bytes,
					(packets * (packetsize + tssize)) -
					bytes)) < 0) {
					fprintf (stderr, "%s: ", argv[0]);
					perror ("unable to write to output");
					free (data);
					return -1;
				}
				bytes += retcode;
			}
			packets = 0;
		} else {
			/* The number of packets to write is greater than
			 * or equal to the buffer size or is infinite (-1). */
			while (bytes < bufsize) {
				if ((retcode = write (STDOUT_FILENO,
					data + bytes, bufsize - bytes)) < 0) {
					fprintf (stderr, "%s: ", argv[0]);
					perror ("unable to write to output");
					free (data);
					return -1;
				}
				bytes += retcode;
			}
			if (packets > 0) {
				packets -= BUFFERED_PACKETS;
			}
			if (bitrate > 0) {
				update_timestamps (data,
					&timestamp,
					&sum,
					bitrate,
					packetsize);
			}
		}
	}
	free (data);
	return 0;

USAGE:
	fprintf (stderr, "Try '%s -h' for more information.\n", argv[0]);
	return -1;
}