Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 26 Sep 2011 17:22:05 +0000 (19:22 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 26 Sep 2011 17:22:05 +0000 (19:22 +0200)
Conflicts:
gst-libs/gst/audio/gstaudiodecoder.c
gst-libs/gst/audio/gstaudioencoder.c
gst/encoding/gstencodebin.c

1  2 
docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/audio/gstaudiodecoder.c
gst-libs/gst/audio/gstaudiodecoder.h
gst-libs/gst/audio/gstaudioencoder.c
gst-libs/gst/audio/gstaudioencoder.h
win32/common/libgstaudio.def

@@@ -453,8 -471,13 +463,10 @@@ gst_audio_decoder_src_setcaps (GstAudio
    gboolean res = TRUE;
    guint old_rate;
  
 -  dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
 -
    GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
  
+   GST_AUDIO_DECODER_STREAM_LOCK (dec);
    /* parse caps here to check subclass;
     * also makes us aware of output format */
    if (!gst_caps_is_fixed (caps))
@@@ -493,9 -521,9 +508,10 @@@ gst_audio_decoder_sink_setcaps (GstAudi
  
    GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
  
+   GST_AUDIO_DECODER_STREAM_LOCK (dec);
    /* NOTE pbutils only needed here */
    /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */
 +#if 0
    if (dec->priv->taglist)
      gst_tag_list_free (dec->priv->taglist);
    dec->priv->taglist = gst_tag_list_new ();
    if (klass->set_format)
      res = klass->set_format (dec, caps);
  
 -  g_object_unref (dec);
+   GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
    return res;
  }
  
@@@ -676,30 -708,44 +694,45 @@@ gst_audio_decoder_finish_frame (GstAudi
    GstAudioDecoderContext *ctx;
    gint samples = 0;
    GstClockTime ts, next_ts;
 +  gsize size;
+   GstFlowReturn ret = GST_FLOW_OK;
  
    /* subclass should know what it is producing by now */
 -  g_return_val_if_fail (buf == NULL || GST_PAD_CAPS (dec->srcpad) != NULL,
 +  g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad),
        GST_FLOW_ERROR);
    /* subclass should not hand us no data */
 -  g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0,
 +  g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
        GST_FLOW_ERROR);
    /* no dummy calls please */
    g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
  
    priv = dec->priv;
    ctx = &dec->priv->ctx;
 +  size = buf ? gst_buffer_get_size (buf) : 0;
  
    GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
 -      buf ? GST_BUFFER_SIZE (buf) : -1,
 -      buf ? GST_BUFFER_SIZE (buf) / ctx->info.bpf : -1, frames);
 +      buf ? size : -1, buf ? size / ctx->info.bpf : -1, frames);
  
+   GST_AUDIO_DECODER_STREAM_LOCK (dec);
+   if (priv->pending_events) {
+     GList *pending_events, *l;
+     pending_events = priv->pending_events;
+     priv->pending_events = NULL;
+     GST_DEBUG_OBJECT (dec, "Pushing pending events");
+     for (l = priv->pending_events; l; l = l->next)
+       gst_pad_push_event (dec->srcpad, l->data);
+     g_list_free (pending_events);
+   }
    /* output shoud be whole number of sample frames */
    if (G_LIKELY (buf && ctx->info.bpf)) {
 -    if (GST_BUFFER_SIZE (buf) % ctx->info.bpf)
 +    if (size % ctx->info.bpf)
        goto wrong_buffer;
      /* per channel least */
 -    samples = GST_BUFFER_SIZE (buf) / ctx->info.bpf;
 +    samples = size / ctx->info.bpf;
    }
  
    /* frame and ts book-keeping */
@@@ -806,9 -856,11 +843,10 @@@ exit
  wrong_buffer:
    {
      GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
 -        ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buf),
 -            ctx->info.bpf));
 +        ("buffer size %d not a multiple of %d", size, ctx->info.bpf));
      gst_buffer_unref (buf);
-     return GST_FLOW_ERROR;
+     ret = GST_FLOW_ERROR;
+     goto exit;
    }
  overflow:
    {
@@@ -1265,17 -1322,29 +1308,18 @@@ gst_audio_decoder_sink_eventfunc (GstAu
    gboolean handled = FALSE;
  
    switch (GST_EVENT_TYPE (event)) {
 -    case GST_EVENT_NEWSEGMENT:
 +    case GST_EVENT_SEGMENT:
      {
 -      GstFormat format;
 -      gdouble rate, arate;
 -      gint64 start, stop, time;
 -      gboolean update;
 +      GstSegment seg;
  
 -      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
 -          &start, &stop, &time);
+       GST_AUDIO_DECODER_STREAM_LOCK (dec);
 +      gst_event_copy_segment (event, &seg);
  
 -      if (format == GST_FORMAT_TIME) {
 -        GST_DEBUG_OBJECT (dec, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
 -            " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
 -            ", rate %g, applied_rate %g",
 -            GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time),
 -            rate, arate);
 +      if (seg.format == GST_FORMAT_TIME) {
 +        GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_PTR_FORMAT, &seg);
        } else {
 -        GstFormat dformat = GST_FORMAT_TIME;
 -
 -        GST_DEBUG_OBJECT (dec, "received NEW_SEGMENT %" G_GINT64_FORMAT
 -            " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
 -            ", rate %g, applied_rate %g", start, stop, time, rate, arate);
 +        gint64 nstart;
 +        GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_PTR_FORMAT, &seg);
          /* handle newsegment resulting from legacy simple seeking */
          /* note that we need to convert this whether or not enough data
           * to handle initial newsegment */
            /* as these are only estimates, stop is kept open-ended to avoid
             * premature cutting */
            GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
 -              GST_TIME_ARGS (start));
 -          format = GST_FORMAT_TIME;
 -          time = start;
 -          stop = GST_CLOCK_TIME_NONE;
 +              GST_TIME_ARGS (nstart));
 +          seg.format = GST_FORMAT_TIME;
 +          seg.start = nstart;
 +          seg.time = nstart;
 +          seg.stop = GST_CLOCK_TIME_NONE;
            /* replace event */
            gst_event_unref (event);
 -          event = gst_event_new_new_segment_full (update, rate, arate,
 -              GST_FORMAT_TIME, start, stop, time);
 +          event = gst_event_new_segment (&seg);
          } else {
            GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
+           GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
            break;
          }
        }
        }
  
        /* and follow along with segment */
 -      gst_segment_set_newsegment_full (&dec->segment, update, rate, arate,
 -          format, start, stop, time);
 -
 +      dec->segment = seg;
-       gst_pad_push_event (dec->srcpad, event);
+       dec->priv->pending_events =
+           g_list_append (dec->priv->pending_events, event);
        handled = TRUE;
+       GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
        break;
      }
  
        break;
  
      case GST_EVENT_EOS:
+       GST_AUDIO_DECODER_STREAM_LOCK (dec);
        gst_audio_decoder_drain (dec);
+       GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
        break;
  
 +    case GST_EVENT_CAPS:
 +    {
 +      GstCaps *caps;
 +
 +      gst_event_parse_caps (event, &caps);
 +      gst_audio_decoder_sink_setcaps (dec, caps);
 +      gst_event_unref (event);
 +      handled = TRUE;
 +      break;
 +    }
      default:
        break;
    }
Simple merge
@@@ -400,8 -413,16 +410,16 @@@ gst_audio_encoder_reset (GstAudioEncode
      enc->priv->active = FALSE;
      enc->priv->samples_in = 0;
      enc->priv->bytes_out = 0;
 -    gst_audio_info_clear (&enc->priv->ctx.info);
 +    gst_audio_info_init (&enc->priv->ctx.info);
      memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
+     if (enc->priv->tags)
+       gst_tag_list_free (enc->priv->tags);
+     enc->priv->tags = NULL;
+     g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL);
+     g_list_free (enc->priv->pending_events);
+     enc->priv->pending_events = NULL;
    }
  
    gst_segment_init (&enc->segment, GST_FORMAT_TIME);
@@@ -467,13 -490,30 +487,30 @@@ gst_audio_encoder_finish_frame (GstAudi
    ctx = &enc->priv->ctx;
  
    /* subclass should know what it is producing by now */
 -  g_return_val_if_fail (GST_PAD_CAPS (enc->srcpad) != NULL, GST_FLOW_ERROR);
 +  g_return_val_if_fail (gst_pad_has_current_caps (enc->srcpad), GST_FLOW_ERROR);
    /* subclass should not hand us no data */
 -  g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0,
 +  g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
        GST_FLOW_ERROR);
  
+   GST_AUDIO_ENCODER_STREAM_LOCK (enc);
+   if (G_UNLIKELY (enc->priv->tags)) {
+     GstTagList *tags;
+     /* add codec info to pending tags */
+     tags = enc->priv->tags;
+     /* no more pending */
+     enc->priv->tags = NULL;
+     gst_pb_utils_add_codec_description_to_tag_list (tags, GST_TAG_CODEC,
+         GST_PAD_CAPS (enc->srcpad));
+     gst_pb_utils_add_codec_description_to_tag_list (tags, GST_TAG_AUDIO_CODEC,
+         GST_PAD_CAPS (enc->srcpad));
+     GST_DEBUG_OBJECT (enc, "sending tags %" GST_PTR_FORMAT, tags);
+     gst_element_found_tags_for_pad (GST_ELEMENT (enc), enc->srcpad, tags);
+   }
    GST_LOG_OBJECT (enc, "accepting %d bytes encoded data as %d samples",
 -      buf ? GST_BUFFER_SIZE (buf) : -1, samples);
 +      buf ? gst_buffer_get_size (buf) : -1, samples);
  
    /* mark subclass still alive and providing */
    priv->got_data = TRUE;
@@@ -929,10 -986,11 +994,11 @@@ not_negotiated
  wrong_buffer:
    {
      GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
 -        ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buffer),
 +        ("buffer size %d not a multiple of %d", gst_buffer_get_size (buffer),
              ctx->info.bpf));
      gst_buffer_unref (buffer);
-     return GST_FLOW_ERROR;
+     ret = GST_FLOW_ERROR;
+     goto done;
    }
  }
  
@@@ -970,7 -1030,10 +1036,9 @@@ gst_audio_encoder_sink_setcaps (GstAudi
    g_return_val_if_fail (klass->set_format != NULL, FALSE);
  
    ctx = &enc->priv->ctx;
 -  state = &ctx->info;
  
+   GST_AUDIO_ENCODER_STREAM_LOCK (enc);
    GST_DEBUG_OBJECT (enc, "caps: %" GST_PTR_FORMAT, caps);
  
    if (!gst_caps_is_fixed (caps))
@@@ -1166,7 -1247,9 +1240,8 @@@ gst_audio_encoder_sink_eventfunc (GstAu
        /* reset partially for new segment */
        gst_audio_encoder_reset (enc, FALSE);
        /* and follow along with segment */
 -      gst_segment_set_newsegment_full (&enc->segment, update, rate, arate,
 -          format, start, stop, time);
 +      enc->segment = seg;
+       GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
        break;
      }
  
        break;
  
      case GST_EVENT_EOS:
+       GST_AUDIO_ENCODER_STREAM_LOCK (enc);
        gst_audio_encoder_drain (enc);
+       GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
        break;
  
+     case GST_EVENT_TAG:
+     {
+       GstTagList *tags;
+       gst_event_parse_tag (event, &tags);
+       tags = gst_tag_list_copy (tags);
+       gst_event_unref (event);
+       gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
+       gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
+       event = gst_event_new_tag (tags);
+       GST_OBJECT_LOCK (enc);
+       enc->priv->pending_events =
+           g_list_append (enc->priv->pending_events, event);
+       GST_OBJECT_UNLOCK (enc);
+       handled = TRUE;
+       break;
+     }
 +    case GST_EVENT_CAPS:
 +    {
 +      GstCaps *caps;
 +
 +      gst_event_parse_caps (event, &caps);
 +      gst_audio_encoder_sink_setcaps (enc, caps);
 +      gst_event_unref (event);
 +      handled = TRUE;
 +      break;
 +    }
 +
      default:
        break;
    }
Simple merge
Simple merge