diff options
| -rw-r--r-- | ChangeLog | 10 | ||||
| -rw-r--r-- | gst/qtdemux/qtdemux.c | 355 | 
2 files changed, 292 insertions, 73 deletions
@@ -1,3 +1,13 @@ +2007-07-23  Wim Taymans  <wim.taymans@gmail.com> + +	* gst/qtdemux/qtdemux.c: (gst_qtdemux_activate_segment), +	(gst_qtdemux_clip_buffer), (gst_qtdemux_loop_state_movie), +	(qtdemux_parse_trak), (qtdemux_video_caps), (qtdemux_audio_caps): +	Clip raw audio and video when we can, keep track of current output +	segment. +	Don't leak buffers and events when there is no output pad. +	Improve debugging here and there. +  2007-07-23  Stefan Kost  <ensonic@users.sf.net>  	* configure.ac: diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index 72a67d4d..5ecc515e 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -151,11 +151,18 @@ struct _QtDemuxStream    /* when a discontinuity is pending */    gboolean discont; +  /* if we need to clip this buffer. This is only needed for uncompressed +   * data */ +  gboolean need_clip; +    /* current position */    guint32 segment_index;    guint32 sample_index;    guint64 time_position;        /* in gst time */ +  /* the Gst segment we are processing out, used for clipping */ +  GstSegment segment; +    /* last GstFlowReturn */    GstFlowReturn last_ret; @@ -226,8 +233,9 @@ static gboolean qtdemux_parse_tree (GstQTDemux * qtdemux);  static void gst_qtdemux_handle_esds (GstQTDemux * qtdemux,      QtDemuxStream * stream, GNode * esds, GstTagList * list); -static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc, -    const guint8 * stsd_data, const gchar ** codec_name); +static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux, +    QtDemuxStream * stream, guint32 fourcc, const guint8 * stsd_data, +    const gchar ** codec_name);  static GstCaps *qtdemux_audio_caps (GstQTDemux * qtdemux,      QtDemuxStream * stream, guint32 fourcc, const guint8 * data, int len,      const gchar ** codec_name); @@ -1066,11 +1074,18 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,    /* combine global rate with that of the segment */    rate = segment->rate * qtdemux->segment.rate; -  event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME, + +  /* update the segment values used for clipping */ +  gst_segment_init (&stream->segment, GST_FORMAT_TIME); +  gst_segment_set_newsegment (&stream->segment, FALSE, rate, GST_FORMAT_TIME,        start, stop, offset); -  if (stream->pad) +  /* now prepare and send the segment */ +  if (stream->pad) { +    event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME, +        start, stop, offset);      gst_pad_push_event (stream->pad, event); +  }    /* and move to the keyframe before the indicated media time of the     * segment */ @@ -1255,6 +1270,116 @@ done:    return ret;  } +/* the input buffer metadata must be writable. Returns NULL when the buffer is + * completely cliped */ +static GstBuffer * +gst_qtdemux_clip_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream, +    GstBuffer * buf) +{ +  gint64 start, stop, cstart, cstop, diff; +  GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE; +  guint8 *data; +  guint size; +  gint num_rate, denom_rate; +  gint frame_size; +  gboolean clip_data; + +  data = GST_BUFFER_DATA (buf); +  size = GST_BUFFER_SIZE (buf); + +  /* depending on the type, setup the clip parameters */ +  if (stream->subtype == FOURCC_soun) { +    frame_size = stream->bytes_per_frame; +    num_rate = GST_SECOND; +    denom_rate = (gint) stream->rate; +    clip_data = TRUE; +  } else if (stream->subtype == FOURCC_vide) { +    frame_size = size; +    num_rate = stream->fps_n; +    denom_rate = stream->fps_d; +    clip_data = FALSE; +  } else +    goto wrong_type; + +  /* we can only clip if we have a valid timestamp */ +  timestamp = GST_BUFFER_TIMESTAMP (buf); +  if (!GST_CLOCK_TIME_IS_VALID (timestamp)) +    goto no_timestamp; + +  if (GST_BUFFER_DURATION_IS_VALID (buf)) { +    duration = GST_BUFFER_DURATION (buf); +  } else { +    duration = +        gst_util_uint64_scale_int (size / frame_size, num_rate, denom_rate); +  } + +  start = timestamp; +  stop = start + duration; + +  if (!gst_segment_clip (&stream->segment, GST_FORMAT_TIME, +          start, stop, &cstart, &cstop)) +    goto clipped; + +  /* see if some clipping happened */ +  diff = cstart - start; +  if (diff > 0) { +    timestamp = cstart; +    duration -= diff; + +    if (clip_data) { +      /* bring clipped time to samples and to bytes */ +      diff = gst_util_uint64_scale_int (diff, denom_rate, num_rate); +      diff *= frame_size; + +      GST_DEBUG_OBJECT (qtdemux, "clipping start to %" GST_TIME_FORMAT " %" +          G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstart), diff); + +      data += diff; +      size -= diff; +    } +  } +  diff = stop - cstop; +  if (diff > 0) { +    duration -= diff; + +    if (clip_data) { +      /* bring clipped time to samples and then to bytes */ +      diff = gst_util_uint64_scale_int (diff, denom_rate, num_rate); +      diff *= frame_size; + +      GST_DEBUG_OBJECT (qtdemux, "clipping stop to %" GST_TIME_FORMAT " %" +          G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff); + +      size -= diff; +    } +  } + +  GST_BUFFER_TIMESTAMP (buf) = timestamp; +  GST_BUFFER_DURATION (buf) = duration; +  GST_BUFFER_SIZE (buf) = size; +  GST_BUFFER_DATA (buf) = data; + +  return buf; + +  /* dropped buffer */ +wrong_type: +  { +    GST_DEBUG_OBJECT (qtdemux, "unknown stream type"); +    return buf; +  } +no_timestamp: +  { +    GST_DEBUG_OBJECT (qtdemux, "no timestamp on buffer"); +    return buf; +  } +clipped: +  { +    GST_DEBUG_OBJECT (qtdemux, "clipped buffer"); +    gst_buffer_unref (buf); +    return NULL; +  } +} +  static GstFlowReturn  gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)  { @@ -1302,9 +1427,9 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)      goto eos;    GST_LOG_OBJECT (qtdemux, -      "pushing from stream %d, offset=%" G_GUINT64_FORMAT -      ",size=%d timestamp=%" GST_TIME_FORMAT, -      index, offset, size, GST_TIME_ARGS (timestamp)); +      "pushing from stream %d, offset %" G_GUINT64_FORMAT +      ", size %d, timestamp=%" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT, +      index, offset, size, GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));    /* hmm, empty sample, skip and move to next sample */    if (G_UNLIKELY (size <= 0)) @@ -1339,14 +1464,17 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)      /* we're going to modify the metadata */      buf = gst_buffer_make_metadata_writable (buf); +    GST_BUFFER_TIMESTAMP (buf) = timestamp; +    GST_BUFFER_DURATION (buf) = duration; + +    if (stream->need_clip) +      buf = gst_qtdemux_clip_buffer (qtdemux, stream, buf); +      if (stream->discont) {        GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);        stream->discont = FALSE;      } -    GST_BUFFER_TIMESTAMP (buf) = timestamp; -    GST_BUFFER_DURATION (buf) = duration; -      if (!keyframe)        GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); @@ -1355,10 +1483,13 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)      GST_LOG_OBJECT (qtdemux,          "Pushing buffer with time %" GST_TIME_FORMAT ", duration %"          GST_TIME_FORMAT " on pad %s", -        GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration), -        GST_PAD_NAME (stream->pad)); +        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), +        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_PAD_NAME (stream->pad)); +      ret = gst_pad_push (stream->pad, buf);    } else { +    GST_DEBUG_OBJECT (qtdemux, "No output pad for stream, ignoring"); +    gst_buffer_unref (buf);      ret = GST_FLOW_OK;    } @@ -2643,9 +2774,11 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)    const guint8 *stsd_data;    guint32 version; -  /* new streams always need a discont */    stream = g_new0 (QtDemuxStream, 1); +  /* new streams always need a discont */    stream->discont = TRUE; +  /* we enable clipping for raw audio/video streams */ +  stream->need_clip = FALSE;    stream->segment_index = -1;    stream->time_position = 0;    stream->sample_index = 0; @@ -2745,7 +2878,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)      if (fourcc == FOURCC_drms)        goto error_encrypted; -    stream->caps = qtdemux_video_caps (qtdemux, fourcc, stsd_data, &codec); +    stream->caps = +        qtdemux_video_caps (qtdemux, stream, fourcc, stsd_data, &codec);      if (codec) {        list = gst_tag_list_new ();        gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, @@ -3694,35 +3828,44 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,    } while (0)  static GstCaps * -qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc, -    const guint8 * stsd_data, const gchar ** codec_name) +qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream, +    guint32 fourcc, const guint8 * stsd_data, const gchar ** codec_name)  { +  GstCaps *caps; +  const GstStructure *s; +  const gchar *name; +    switch (fourcc) {      case GST_MAKE_FOURCC ('p', 'n', 'g', ' '):        _codec ("PNG still images"); -      return gst_caps_from_string ("image/png"); +      caps = gst_caps_from_string ("image/png"); +      break;      case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'):        _codec ("JPEG still images"); -      return gst_caps_from_string ("image/jpeg"); +      caps = gst_caps_from_string ("image/jpeg"); +      break;      case GST_MAKE_FOURCC ('m', 'j', 'p', 'a'):      case GST_MAKE_FOURCC ('A', 'V', 'D', 'J'):      case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'):        _codec ("Motion-JPEG"); -      return gst_caps_from_string ("image/jpeg"); +      caps = gst_caps_from_string ("image/jpeg"); +      break;      case GST_MAKE_FOURCC ('m', 'j', 'p', 'b'):        _codec ("Motion-JPEG format B"); -      return gst_caps_from_string ("video/x-mjpeg-b"); +      caps = gst_caps_from_string ("video/x-mjpeg-b"); +      break;      case GST_MAKE_FOURCC ('S', 'V', 'Q', '3'):        _codec ("Sorensen video v.3"); -      return gst_caps_from_string ("video/x-svq, " "svqversion = (int) 3"); +      caps = gst_caps_from_string ("video/x-svq, " "svqversion = (int) 3"); +      break;      case GST_MAKE_FOURCC ('s', 'v', 'q', 'i'):      case GST_MAKE_FOURCC ('S', 'V', 'Q', '1'):        _codec ("Sorensen video v.1"); -      return gst_caps_from_string ("video/x-svq, " "svqversion = (int) 1"); +      caps = gst_caps_from_string ("video/x-svq, " "svqversion = (int) 1"); +      break;      case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):      {        guint16 bps; -      GstCaps *caps;        _codec ("Raw RGB video");        bps = QT_UINT16 (stsd_data + 98); @@ -3769,75 +3912,93 @@ qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc,            /* unknown */            break;        } -      return caps; +      break;      }      case GST_MAKE_FOURCC ('y', 'v', '1', '2'):        _codec ("Raw planar YUV 4:2:0"); -      return gst_caps_from_string ("video/x-raw-yuv, " +      caps = gst_caps_from_string ("video/x-raw-yuv, "            "format = (fourcc) I420"); +      break;      case GST_MAKE_FOURCC ('y', 'u', 'v', '2'):      case GST_MAKE_FOURCC ('Y', 'u', 'v', '2'):        _codec ("Raw packed YUV 4:2:2"); -      return gst_caps_from_string ("video/x-raw-yuv, " +      caps = gst_caps_from_string ("video/x-raw-yuv, "            "format = (fourcc) YUY2"); +      break;      case GST_MAKE_FOURCC ('m', 'p', 'e', 'g'):        _codec ("MPEG-1 video"); -      return gst_caps_from_string ("video/mpeg, " +      caps = gst_caps_from_string ("video/mpeg, "            "systemstream = (boolean) false, " "mpegversion = (int) 1"); +      break;      case GST_MAKE_FOURCC ('g', 'i', 'f', ' '):        _codec ("GIF still images"); -      return gst_caps_from_string ("image/gif"); +      caps = gst_caps_from_string ("image/gif"); +      break;      case GST_MAKE_FOURCC ('h', '2', '6', '3'):      case GST_MAKE_FOURCC ('H', '2', '6', '3'):      case GST_MAKE_FOURCC ('s', '2', '6', '3'):      case GST_MAKE_FOURCC ('U', '2', '6', '3'):        _codec ("H.263");        /* ffmpeg uses the height/width props, don't know why */ -      return gst_caps_from_string ("video/x-h263"); +      caps = gst_caps_from_string ("video/x-h263"); +      break;      case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):        _codec ("MPEG-4 video"); -      return gst_caps_from_string ("video/mpeg, " +      caps = gst_caps_from_string ("video/mpeg, "            "mpegversion = (int) 4, " "systemstream = (boolean) false"); +      break;      case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'):      case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'):        _codec ("Microsoft MPEG-4 4.3");  /* FIXME? */ -      return gst_caps_from_string ("video/x-msmpeg, msmpegversion = (int) 43"); +      caps = gst_caps_from_string ("video/x-msmpeg, msmpegversion = (int) 43"); +      break;      case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):      case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):        _codec ("3ivX video"); -      return gst_caps_from_string ("video/x-3ivx"); +      caps = gst_caps_from_string ("video/x-3ivx"); +      break;      case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):        _codec ("DivX 3"); -      return gst_caps_from_string ("video/x-divx," "divxversion= (int) 3"); +      caps = gst_caps_from_string ("video/x-divx," "divxversion= (int) 3"); +      break;      case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):        _codec ("DivX 4"); -      return gst_caps_from_string ("video/x-divx," "divxversion= (int) 4"); +      caps = gst_caps_from_string ("video/x-divx," "divxversion= (int) 4"); +      break;      case GST_MAKE_FOURCC ('D', 'X', '5', '0'):        _codec ("DivX 5"); -      return gst_caps_from_string ("video/x-divx," "divxversion= (int) 5"); +      caps = gst_caps_from_string ("video/x-divx," "divxversion= (int) 5"); +      break;      case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):        _codec ("Cinepak"); -      return gst_caps_from_string ("video/x-cinepak"); +      caps = gst_caps_from_string ("video/x-cinepak"); +      break;      case GST_MAKE_FOURCC ('q', 'd', 'r', 'w'):        _codec ("Apple QuickDraw"); -      return gst_caps_from_string ("video/x-qdrw"); +      caps = gst_caps_from_string ("video/x-qdrw"); +      break;      case GST_MAKE_FOURCC ('r', 'p', 'z', 'a'):        _codec ("Apple video"); -      return gst_caps_from_string ("video/x-apple-video"); +      caps = gst_caps_from_string ("video/x-apple-video"); +      break;      case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):        _codec ("H.264 / AVC"); -      return gst_caps_from_string ("video/x-h264"); +      caps = gst_caps_from_string ("video/x-h264"); +      break;      case GST_MAKE_FOURCC ('r', 'l', 'e', ' '):        _codec ("Run-length encoding"); -      return gst_caps_from_string ("video/x-rle, layout=(string)quicktime"); +      caps = gst_caps_from_string ("video/x-rle, layout=(string)quicktime"); +      break;      case GST_MAKE_FOURCC ('i', 'v', '3', '2'):        _codec ("Indeo Video 3"); -      return gst_caps_from_string ("video/x-indeo, indeoversion=(int)3"); +      caps = gst_caps_from_string ("video/x-indeo, indeoversion=(int)3"); +      break;      case GST_MAKE_FOURCC ('I', 'V', '4', '1'):      case GST_MAKE_FOURCC ('i', 'v', '4', '1'):        _codec ("Intel Video 4"); -      return gst_caps_from_string ("video/x-indeo, indeoversion=(int)4"); +      caps = gst_caps_from_string ("video/x-indeo, indeoversion=(int)4"); +      break;      case GST_MAKE_FOURCC ('d', 'v', 'c', 'p'):      case GST_MAKE_FOURCC ('d', 'v', 'c', ' '):      case GST_MAKE_FOURCC ('d', 'v', 's', 'd'): @@ -3847,13 +4008,16 @@ qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc,      case GST_MAKE_FOURCC ('d', 'v', '2', '5'):      case GST_MAKE_FOURCC ('d', 'v', 'p', 'p'):        _codec ("DV Video"); -      return gst_caps_from_string ("video/x-dv, systemstream=(boolean)false"); +      caps = gst_caps_from_string ("video/x-dv, systemstream=(boolean)false"); +      break;      case GST_MAKE_FOURCC ('s', 'm', 'c', ' '):        _codec ("Apple Graphics (SMC)"); -      return gst_caps_from_string ("video/x-smc"); +      caps = gst_caps_from_string ("video/x-smc"); +      break;      case GST_MAKE_FOURCC ('V', 'P', '3', '1'):        _codec ("VP3"); -      return gst_caps_from_string ("video/x-vp3"); +      caps = gst_caps_from_string ("video/x-vp3"); +      break;      case GST_MAKE_FOURCC ('k', 'p', 'c', 'd'):      default:      { @@ -3861,140 +4025,176 @@ qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc,        s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT,            GST_FOURCC_ARGS (fourcc)); -      return gst_caps_new_simple (s, NULL); +      caps = gst_caps_new_simple (s, NULL); +      break;      }    } + +  /* enable clipping for raw video streams */ +  s = gst_caps_get_structure (caps, 0); +  name = gst_structure_get_name (s); +  if (g_str_has_prefix (name, "video/x-raw-")) { +    stream->need_clip = TRUE; +  } +  return caps;  }  static GstCaps *  qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,      guint32 fourcc, const guint8 * data, int len, const gchar ** codec_name)  { +  GstCaps *caps; +  const GstStructure *s; +  const gchar *name; +    switch (fourcc) {      case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'):      case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):        _codec ("Raw 8-bit PCM audio");        /* FIXME */ -      return gst_caps_from_string ("audio/x-raw-int, " +      caps = gst_caps_from_string ("audio/x-raw-int, "            "width = (int) 8, " "depth = (int) 8, " "signed = (boolean) false"); +      break;      case GST_MAKE_FOURCC ('t', 'w', 'o', 's'):        if (stream->bytes_per_frame == 1) {          _codec ("Raw 8-bit PCM audio"); -        return gst_caps_from_string ("audio/x-raw-int, " +        caps = gst_caps_from_string ("audio/x-raw-int, "              "width = (int) 8, " "depth = (int) 8, " "signed = (boolean) true");        } else {          _codec ("Raw 16-bit PCM audio");          /* FIXME */ -        return gst_caps_from_string ("audio/x-raw-int, " +        caps = gst_caps_from_string ("audio/x-raw-int, "              "width = (int) 16, "              "depth = (int) 16, "              "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true");        } +      break;      case GST_MAKE_FOURCC ('s', 'o', 'w', 't'):        if (stream->bytes_per_frame == 1) {          _codec ("Raw 8-bit PCM audio"); -        return gst_caps_from_string ("audio/x-raw-int, " +        caps = gst_caps_from_string ("audio/x-raw-int, "              "width = (int) 8, " "depth = (int) 8, " "signed = (boolean) true");        } else {          _codec ("Raw 16-bit PCM audio");          /* FIXME */ -        return gst_caps_from_string ("audio/x-raw-int, " +        caps = gst_caps_from_string ("audio/x-raw-int, "              "width = (int) 16, "              "depth = (int) 16, "              "endianness = (int) LITTLE_ENDIAN, " "signed = (boolean) true");        } +      break;      case GST_MAKE_FOURCC ('f', 'l', '6', '4'):        _codec ("Raw 64-bit floating-point audio"); -      return gst_caps_from_string ("audio/x-raw-float, " +      caps = gst_caps_from_string ("audio/x-raw-float, "            "width = (int) 64, " "endianness = (int) BIG_ENDIAN"); +      break;      case GST_MAKE_FOURCC ('f', 'l', '3', '2'):        _codec ("Raw 32-bit floating-point audio"); -      return gst_caps_from_string ("audio/x-raw-float, " +      caps = gst_caps_from_string ("audio/x-raw-float, "            "width = (int) 32, " "endianness = (int) BIG_ENDIAN"); +      break;      case GST_MAKE_FOURCC ('i', 'n', '2', '4'):        _codec ("Raw 24-bit PCM audio");        /* FIXME */ -      return gst_caps_from_string ("audio/x-raw-int, " +      caps = gst_caps_from_string ("audio/x-raw-int, "            "width = (int) 24, "            "depth = (int) 24, "            "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true"); +      break;      case GST_MAKE_FOURCC ('i', 'n', '3', '2'):        _codec ("Raw 32-bit PCM audio");        /* FIXME */ -      return gst_caps_from_string ("audio/x-raw-int, " +      caps = gst_caps_from_string ("audio/x-raw-int, "            "width = (int) 32, "            "depth = (int) 32, "            "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true"); +      break;      case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):        _codec ("Mu-law audio");        /* FIXME */ -      return gst_caps_from_string ("audio/x-mulaw"); +      caps = gst_caps_from_string ("audio/x-mulaw"); +      break;      case GST_MAKE_FOURCC ('a', 'l', 'a', 'w'):        _codec ("A-law audio");        /* FIXME */ -      return gst_caps_from_string ("audio/x-alaw"); +      caps = gst_caps_from_string ("audio/x-alaw"); +      break;      case 0x6d730002:        _codec ("Microsoft ADPCM");        /* Microsoft ADPCM-ACM code 2 */ -      return gst_caps_from_string ("audio/x-adpcm, " +      caps = gst_caps_from_string ("audio/x-adpcm, "            "layout = (string) microsoft"); +      break;      case 0x6d730011:      case 0x6d730017:        _codec ("DVI/Intel IMA ADPCM");        /* FIXME DVI/Intel IMA ADPCM/ACM code 17 */ -      return gst_caps_from_string ("audio/x-adpcm, " +      caps = gst_caps_from_string ("audio/x-adpcm, "            "layout = (string) quicktime"); +      break;      case 0x6d730055:        /* MPEG layer 3, CBR only (pre QT4.1) */      case 0x5500736d:      case GST_MAKE_FOURCC ('.', 'm', 'p', '3'):        _codec ("MPEG-1 layer 3");        /* MPEG layer 3, CBR & VBR (QT4.1 and later) */ -      return gst_caps_from_string ("audio/mpeg, " +      caps = gst_caps_from_string ("audio/mpeg, "            "layer = (int) 3, " "mpegversion = (int) 1"); +      break;      case GST_MAKE_FOURCC ('M', 'A', 'C', '3'):        _codec ("MACE-3"); -      return gst_caps_from_string ("audio/x-mace, " "maceversion = (int) 3"); +      caps = gst_caps_from_string ("audio/x-mace, " "maceversion = (int) 3"); +      break;      case GST_MAKE_FOURCC ('M', 'A', 'C', '6'):        _codec ("MACE-6"); -      return gst_caps_from_string ("audio/x-mace, " "maceversion = (int) 6"); +      caps = gst_caps_from_string ("audio/x-mace, " "maceversion = (int) 6"); +      break;      case GST_MAKE_FOURCC ('O', 'g', 'g', 'V'):        /* ogg/vorbis */ -      return gst_caps_from_string ("application/ogg"); +      caps = gst_caps_from_string ("application/ogg"); +      break;      case GST_MAKE_FOURCC ('d', 'v', 'c', 'a'):        _codec ("DV audio"); -      return gst_caps_from_string ("audio/x-dv"); +      caps = gst_caps_from_string ("audio/x-dv"); +      break;      case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):        _codec ("MPEG-4 AAC audio"); -      return gst_caps_new_simple ("audio/mpeg", +      caps = gst_caps_new_simple ("audio/mpeg",            "mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE, NULL); +      break;      case GST_MAKE_FOURCC ('Q', 'D', 'M', '2'):        _codec ("QDesign Music v.2");        /* FIXME: QDesign music version 2 (no constant) */        if (data) { -        return gst_caps_new_simple ("audio/x-qdm2", +        caps = gst_caps_new_simple ("audio/x-qdm2",              "framesize", G_TYPE_INT, QT_UINT32 (data + 52),              "bitrate", G_TYPE_INT, QT_UINT32 (data + 40),              "blocksize", G_TYPE_INT, QT_UINT32 (data + 44), NULL);        } else { -        return gst_caps_new_simple ("audio/x-qdm2", NULL); +        caps = gst_caps_new_simple ("audio/x-qdm2", NULL);        } +      break;      case GST_MAKE_FOURCC ('a', 'g', 's', 'm'):        _codec ("GSM audio"); -      return gst_caps_new_simple ("audio/x-gsm", NULL); +      caps = gst_caps_new_simple ("audio/x-gsm", NULL); +      break;      case GST_MAKE_FOURCC ('s', 'a', 'm', 'r'):        _codec ("AMR audio"); -      return gst_caps_new_simple ("audio/AMR", NULL); +      caps = gst_caps_new_simple ("audio/AMR", NULL); +      break;      case GST_MAKE_FOURCC ('s', 'a', 'w', 'b'):        _codec ("AMR-WB audio"); -      return gst_caps_new_simple ("audio/AMR-WB", NULL); +      caps = gst_caps_new_simple ("audio/AMR-WB", NULL); +      break;      case GST_MAKE_FOURCC ('i', 'm', 'a', '4'):        _codec ("Quicktime IMA ADPCM"); -      return gst_caps_new_simple ("audio/x-adpcm", +      caps = gst_caps_new_simple ("audio/x-adpcm",            "layout", G_TYPE_STRING, "quicktime", NULL); +      break;      case GST_MAKE_FOURCC ('a', 'l', 'a', 'c'):        _codec ("Apple lossless audio"); -      return gst_caps_new_simple ("audio/x-alac", NULL); +      caps = gst_caps_new_simple ("audio/x-alac", NULL); +      break;      case GST_MAKE_FOURCC ('q', 't', 'v', 'r'):        /* ? */      case GST_MAKE_FOURCC ('Q', 'D', 'M', 'C'): @@ -4007,7 +4207,16 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,        s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,            GST_FOURCC_ARGS (fourcc)); -      return gst_caps_new_simple (s, NULL); +      caps = gst_caps_new_simple (s, NULL); +      break;      }    } + +  /* enable clipping for raw audio streams */ +  s = gst_caps_get_structure (caps, 0); +  name = gst_structure_get_name (s); +  if (g_str_has_prefix (name, "audio/x-raw-")) { +    stream->need_clip = TRUE; +  } +  return caps;  }  | 
