gst-gmyth/mythsrc/gstmythtvsrc.c
branchtrunk
changeset 824 e711a64ba03d
parent 812 cf7e02ee3db4
child 829 0a4e6b811acc
     1.1 --- a/gst-gmyth/mythsrc/gstmythtvsrc.c	Mon Aug 20 19:03:06 2007 +0100
     1.2 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.c	Thu Aug 23 20:24:11 2007 +0100
     1.3 @@ -87,10 +87,8 @@
     1.4  #define GMYTHTV_TRANSFER_MAX_WAITS          100
     1.5  #define GMYTHTV_TRANSFER_MAX_RESENDS        2
     1.6  #define GMYTHTV_TRANSFER_MAX_BUFFER         (128*1024)
     1.7 -#define MAX_READ_SIZE                       (4*1024)
     1.8 +#define READ_SIZE                           (4*1024)
     1.9  #define GST_FLOW_ERROR_NO_DATA              (-101)
    1.10 -#define REQUEST_MAX_SIZE                    (64*1024)
    1.11 -#define INTERNAL_BUFFER_SIZE                (90*1024)
    1.12  
    1.13  static const GstElementDetails gst_mythtv_src_details =
    1.14  GST_ELEMENT_DETAILS("MythTV client source",
    1.15 @@ -254,7 +252,6 @@
    1.16      gstbasesrc_class->stop = gst_mythtv_src_stop;
    1.17      gstbasesrc_class->get_size = gst_mythtv_src_get_size;
    1.18      gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
    1.19 -
    1.20      gstbasesrc_class->do_seek = gst_mythtv_src_do_seek;
    1.21      gstpushsrc_class->create = gst_mythtv_src_create;
    1.22  
    1.23 @@ -281,7 +278,6 @@
    1.24      this->update_prog_chain = FALSE;
    1.25      this->channel_name = NULL;
    1.26      this->eos = FALSE;
    1.27 -    this->bytes_queue = NULL;
    1.28      this->wait_to_transfer = 0;
    1.29      gst_base_src_set_format(GST_BASE_SRC(this), GST_FORMAT_BYTES);
    1.30      gst_pad_set_event_function(GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
    1.31 @@ -310,11 +306,6 @@
    1.32          g_object_unref(mythtv_src->backend_info);
    1.33          mythtv_src->backend_info = NULL;
    1.34      }
    1.35 -
    1.36 -    if (mythtv_src->bytes_queue) {
    1.37 -        g_byte_array_free(mythtv_src->bytes_queue, TRUE);
    1.38 -        mythtv_src->bytes_queue = NULL;
    1.39 -    }
    1.40  }
    1.41  
    1.42  static void
    1.43 @@ -378,17 +369,9 @@
    1.44                  if (result == GMYTH_FILE_READ_ERROR) {  /* -314 */
    1.45                      GST_INFO_OBJECT(src,
    1.46                                      "[LiveTV] FileTransfer READ_ERROR!");
    1.47 -                    goto done;
    1.48 -                } else if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) { /* -315 
    1.49 -                                                                         */
    1.50 -                    GST_INFO_OBJECT(src,
    1.51 -                                    "[LiveTV] FileTransfer - Go to athe next program chain!");
    1.52 -                    src->update_prog_chain = TRUE;
    1.53 -                    continue;
    1.54                  }
    1.55                  goto done;
    1.56              }
    1.57 -
    1.58          }
    1.59          /*
    1.60           * else if (data_ptr->len == 0) goto done; 
    1.61 @@ -414,214 +397,57 @@
    1.62  static GstFlowReturn
    1.63  gst_mythtv_src_create(GstPushSrc * psrc, GstBuffer ** outbuf)
    1.64  {
    1.65 -    GstMythtvSrc   *src;
    1.66 +    GstMythtvSrc  *src;
    1.67      GstFlowReturn   ret = GST_FLOW_OK;
    1.68 -    guint           buffer_size_inter = 0;
    1.69 +    GByteArray *buffer;
    1.70 +    gint buffer_remain = 0;
    1.71 +    GMythFileReadResult result = GMYTH_FILE_READ_OK;
    1.72 +    gboolean buffering = FALSE;
    1.73  
    1.74      src = GST_MYTHTV_SRC(psrc);
    1.75  
    1.76 -    /*
    1.77 -     * The caller should know the number of bytes and not read beyond EOS. 
    1.78 -     */
    1.79 -    if (G_UNLIKELY(src->eos))
    1.80 -        goto eos;
    1.81 -    GST_DEBUG_OBJECT(src, "offset = %" G_GUINT64_FORMAT ", size = %d...",
    1.82 -                     src->read_offset, MAX_READ_SIZE);
    1.83 +    buffer = g_byte_array_new ();
    1.84 +    result = do_read_request_response(src, READ_SIZE, buffer);
    1.85 +    if (result == GMYTH_FILE_READ_ERROR)
    1.86 +        goto read_error;
    1.87  
    1.88 -    GST_DEBUG_OBJECT(src, "Create: buffer_remain: %d, buffer_size = %d.",
    1.89 -                     (gint) src->buffer_remain, src->bytes_queue->len);
    1.90 -
    1.91 -  program_chain_changed:
    1.92 -    /*
    1.93 -     * just get from the byte array, no network effort... 
    1.94 -     */
    1.95 -    if ((src->buffer_remain = src->bytes_queue->len) < MAX_READ_SIZE) {
    1.96 -        GByteArray     *buffer;
    1.97 -        GMythFileReadResult result = GMYTH_FILE_READ_OK;
    1.98 -
    1.99 -        buffer = NULL;
   1.100 -        buffer_size_inter = (INTERNAL_BUFFER_SIZE - src->buffer_remain);
   1.101 -
   1.102 -        if (buffer_size_inter > REQUEST_MAX_SIZE)
   1.103 -            buffer_size_inter = REQUEST_MAX_SIZE;
   1.104 -
   1.105 -        buffer = g_byte_array_new();
   1.106 -
   1.107 -        result = do_read_request_response(src, buffer_size_inter, buffer);
   1.108 -
   1.109 -        /*
   1.110 -         * got the next program info? 
   1.111 -         */
   1.112 -        if (G_UNLIKELY(src->update_prog_chain) || 
   1.113 -            (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN)) {
   1.114 -            GST_DEBUG_OBJECT(src,
   1.115 -                             "Update PROGRAM CHAIN!!! buffer_size = %d.",
   1.116 -                             src->bytes_queue->len);
   1.117 -            gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(psrc)),
   1.118 -                               gst_event_new_custom
   1.119 -                               (GST_EVENT_CUSTOM_DOWNSTREAM, NULL));
   1.120 -            /*
   1.121 -             * gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
   1.122 -             * gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0,
   1.123 -             * -1, 0)); 
   1.124 -             */
   1.125 -            src->update_prog_chain = FALSE;
   1.126 -            src->eos = FALSE;
   1.127 -
   1.128 -            if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) {
   1.129 -                /*
   1.130 -                 * if (buffer != NULL) { g_byte_array_free (buffer, TRUE);
   1.131 -                 * buffer = NULL; } goto program_chain_changed; 
   1.132 -                 */
   1.133 -            } else if (result == GMYTH_FILE_READ_OK) {
   1.134 -                /*
   1.135 -                 * remove wasteful, NUV file header data 
   1.136 -                 */
   1.137 -                /*
   1.138 -                 * buffer = g_byte_array_remove_range( buffer, 0, 512 ); 
   1.139 -                 */
   1.140 -                /*
   1.141 -                 * TODO: need to send a new segment event to NUVDemux? 
   1.142 -                 */
   1.143 -                // gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC
   1.144 -                // (psrc)),
   1.145 -                // gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 
   1.146 -                // 0, -1, 0));
   1.147 -
   1.148 -                /*
   1.149 -                 * goto change_progchain; 
   1.150 -                 */
   1.151 -            }
   1.152 -
   1.153 -        }
   1.154 -        /*
   1.155 -         */
   1.156 -        if (G_UNLIKELY(buffer->len < 0)) {
   1.157 -            if (buffer != NULL) {
   1.158 -                g_byte_array_free(buffer, TRUE);
   1.159 -                buffer = NULL;
   1.160 -            }
   1.161 -
   1.162 -            if (src->live_tv || 
   1.163 -                (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN))
   1.164 -                goto change_progchain;
   1.165 -            else
   1.166 -                goto read_error;
   1.167 -        } else if (G_UNLIKELY(buffer->len == 0)) {
   1.168 -
   1.169 -            if (buffer != NULL) {
   1.170 -                g_byte_array_free(buffer, TRUE);
   1.171 -                buffer = NULL;
   1.172 -            }
   1.173 -
   1.174 -            if (!src->live_tv) {
   1.175 -                if (src->eos)
   1.176 -                    goto eos;
   1.177 -                else 
   1.178 -                    goto done;
   1.179 -            }
   1.180 -            else
   1.181 -                goto program_chain_changed;
   1.182 -        }
   1.183 -
   1.184 -        src->bytes_queue =
   1.185 -            g_byte_array_append(src->bytes_queue, buffer->data,
   1.186 -                                buffer->len);
   1.187 -        if (buffer->len > buffer_size_inter)
   1.188 -            GST_WARNING_OBJECT(src,
   1.189 -                               "INCREASED buffer size! Backend sent more than we ask him... (%d)",
   1.190 -                               abs(buffer->len - buffer_size_inter));
   1.191 -
   1.192 -        src->buffer_remain += buffer->len;
   1.193 -
   1.194 -        if (buffer != NULL) {
   1.195 -            g_byte_array_free(buffer, TRUE);
   1.196 -            buffer = NULL;
   1.197 -        }
   1.198 -
   1.199 -        /*
   1.200 -         * GST_DEBUG_OBJECT (src, "BYTES READ (actual) = %d, BYTES READ
   1.201 -         * (cumulative) = %llu, " "OFFSET = %llu, CONTENT SIZE = %llu.",
   1.202 -         * read, src->bytes_read, src->read_offset, src->content_size); 
   1.203 -         */
   1.204 -    }
   1.205 -
   1.206 -    guint buffer_size;
   1.207 -    buffer_size = (src->buffer_remain <  MAX_READ_SIZE) ? 
   1.208 -                   src->buffer_remain : 
   1.209 -                   MAX_READ_SIZE;
   1.210  
   1.211      *outbuf = gst_buffer_new();
   1.212 -
   1.213 -    /*
   1.214 -     * GST_DEBUG_OBJECT (src, "read from network? %s!, buffer_remain =
   1.215 -     * %d", (buffer_size_inter == 0) ? "NO, got from buffer" : "YES, go
   1.216 -     * see the backend's log file", src->buffer_remain); 
   1.217 -     */
   1.218 -
   1.219 -    GST_BUFFER_SIZE(*outbuf) = buffer_size;
   1.220 +    GST_BUFFER_SIZE(*outbuf) = buffer->len;
   1.221      GST_BUFFER_MALLOCDATA(*outbuf) = g_malloc0(GST_BUFFER_SIZE(*outbuf));
   1.222      GST_BUFFER_DATA(*outbuf) = GST_BUFFER_MALLOCDATA(*outbuf);
   1.223 -    g_memmove(GST_BUFFER_DATA((*outbuf)), src->bytes_queue->data,
   1.224 +    g_memmove(GST_BUFFER_DATA((*outbuf)), buffer->data,
   1.225                GST_BUFFER_SIZE(*outbuf));
   1.226      GST_BUFFER_OFFSET(*outbuf) = src->read_offset;
   1.227      GST_BUFFER_OFFSET_END(*outbuf) =
   1.228          src->read_offset + GST_BUFFER_SIZE(*outbuf);
   1.229  
   1.230 -    src->buffer_remain -= GST_BUFFER_SIZE(*outbuf);
   1.231 -
   1.232      src->read_offset += GST_BUFFER_SIZE(*outbuf);
   1.233      src->bytes_read += GST_BUFFER_SIZE(*outbuf);
   1.234 -    // GST_DEBUG_OBJECT (src, "Buffer output with size: %d",
   1.235 -    // GST_BUFFER_SIZE (*outbuf));
   1.236  
   1.237 -    /*
   1.238 -     * flushs the newly buffer got from byte array 
   1.239 -     */
   1.240 -    src->bytes_queue =
   1.241 -        g_byte_array_remove_range(src->bytes_queue, 0, buffer_size);
   1.242 +    g_byte_array_free (buffer, TRUE);
   1.243  
   1.244 -    if (src->eos  || 
   1.245 -        (!src->live_tv && (src->bytes_read >= src->content_size))
   1.246 -       )
   1.247 -        goto eos;
   1.248 +    if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) {
   1.249 +        GstPad *peer;
   1.250  
   1.251 -  done:
   1.252 -    {
   1.253 -        return ret;
   1.254 -    }
   1.255 -  eos:
   1.256 -    {
   1.257 -        return GST_FLOW_UNEXPECTED;
   1.258 -    }
   1.259 -    /*
   1.260 -     * ERRORS 
   1.261 -     */
   1.262 -  read_error:
   1.263 -    {
   1.264 -        GST_ELEMENT_ERROR(src, RESOURCE, READ,
   1.265 -                          (NULL), ("Could not read any bytes (%i, %s)",
   1.266 -                                   read, src->uri_name));
   1.267 -        return GST_FLOW_ERROR;
   1.268 -    }
   1.269 -  change_progchain:
   1.270 -    {
   1.271 -        GST_ELEMENT_ERROR(src, RESOURCE, READ,
   1.272 -                          (NULL),
   1.273 -                          ("Seek failed, go to the next program info... (%i, %s)",
   1.274 -                           read, src->uri_name));
   1.275 +        peer = gst_pad_get_peer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)));
   1.276 +        gst_pad_send_event (peer,
   1.277 +            gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0));
   1.278  
   1.279 -        /*
   1.280 -         * TODO: need to send a new segment event to NUVDemux? 
   1.281 -         */
   1.282 -        gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(psrc)),
   1.283 -                           gst_event_new_new_segment(TRUE, 1.0,
   1.284 -                                                     GST_FORMAT_TIME, 0,
   1.285 -                                                     -1, 0));
   1.286 -
   1.287 -        goto program_chain_changed;
   1.288 +        gst_object_unref (peer);
   1.289      }
   1.290  
   1.291 +    if (src->eos  ||
   1.292 +        (!src->live_tv && (src->bytes_read >= src->content_size)))
   1.293 +        ret = GST_FLOW_UNEXPECTED;
   1.294 +
   1.295 +    return ret;
   1.296 +
   1.297 +read_error:
   1.298 +    GST_ELEMENT_ERROR(src, RESOURCE, READ,
   1.299 +        (NULL), ("Could not read any bytes (%i, %s)",
   1.300 +        read, src->uri_name));
   1.301 +    return GST_FLOW_ERROR;
   1.302  }
   1.303  
   1.304  gint64
   1.305 @@ -737,16 +563,10 @@
   1.306      gmyth_uri = gmyth_uri_new_with_value(src->uri_name);
   1.307      src->backend_info = gmyth_backend_info_new_with_uri(src->uri_name);
   1.308      src->live_tv = gmyth_uri_is_livetv(gmyth_uri);
   1.309 -    /*
   1.310 -     * testing UPnP... 
   1.311 -     */
   1.312 -    /*
   1.313 -     * gmyth_backend_info_set_hostname( src->backend_info, NULL ); 
   1.314 -     */
   1.315 +
   1.316      if (src->live_tv) {
   1.317          src->spawn_livetv = gmyth_livetv_new(src->backend_info);
   1.318 -
   1.319 -        gchar          *ch = gmyth_uri_get_channel_name(gmyth_uri);
   1.320 +        gchar *ch = gmyth_uri_get_channel_name(gmyth_uri);
   1.321          if (ch != NULL)
   1.322              src->channel_name = ch;
   1.323  
   1.324 @@ -781,6 +601,7 @@
   1.325              GMYTH_FILE(gmyth_livetv_create_file_transfer
   1.326                         (src->spawn_livetv));
   1.327  
   1.328 +
   1.329          if (NULL == src->file) {
   1.330              GST_INFO_OBJECT(src, "[LiveTV] FileTransfer equals to NULL");
   1.331              ret = FALSE;
   1.332 @@ -862,12 +683,6 @@
   1.333  
   1.334      src->do_start = FALSE;
   1.335  
   1.336 -    /*
   1.337 -     * this is used for the buffer cache 
   1.338 -     */
   1.339 -    src->bytes_queue = g_byte_array_sized_new(INTERNAL_BUFFER_SIZE);
   1.340 -    src->buffer_remain = 0;
   1.341 -
   1.342      gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(src)),
   1.343                         gst_event_new_new_segment(TRUE, 1.0,
   1.344                                                   GST_FORMAT_TIME, 0,
   1.345 @@ -967,11 +782,6 @@
   1.346      GstMythtvSrc   *src = GST_MYTHTV_SRC(bsrc);
   1.347  
   1.348      gst_mythtv_src_clear(src);
   1.349 -
   1.350 -    /*
   1.351 -     * src->eos = FALSE; 
   1.352 -     */
   1.353 -
   1.354      return TRUE;
   1.355  }
   1.356