summaryrefslogtreecommitdiffstats
path: root/gst/avi/riff.c
blob: 5138b8dc2f0c992a1dea9a7d3947b850c06d81ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "riff.h"

GstRiffParse*
gst_riff_parse_new (GstPad *pad)
{
  GstRiffParse *parse;

  parse = g_new0 (GstRiffParse, 1);
  parse->pad = pad;
  parse->bs = gst_bytestream_new (pad);

  return parse;
}

void
gst_riff_parse_free (GstRiffParse *parse)
{
  gst_bytestream_destroy (parse->bs);
  g_free (parse);
}


static GstRiffReturn
gst_riff_parse_handle_sink_event (GstRiffParse *parse)
{
  guint32 remaining;
  GstEvent *event;
  GstEventType type;
  GstRiffReturn ret = GST_RIFF_OK;

  gst_bytestream_get_status (parse->bs, &remaining, &event);

  type = event? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;

  switch (type) {
    case GST_EVENT_EOS:
      ret = GST_RIFF_EOS;
      break;
    default:
      g_warning ("unhandled event %d", type);
      break;
  }

  gst_event_unref (event);

  return ret;
}

GstRiffReturn
gst_riff_parse_next_chunk (GstRiffParse *parse, guint32 *id, GstBuffer **buf)
{
  GstByteStream *bs;
  guint32 got_bytes;
  gint skipsize;
  gst_riff_chunk *chunk;

  bs = parse->bs;

  do {
    got_bytes = gst_bytestream_peek_bytes (bs, (guint8 **) &chunk, sizeof (gst_riff_chunk));
    if (got_bytes < sizeof (gst_riff_chunk)) {
      GstRiffReturn ret;
      
      ret = gst_riff_parse_handle_sink_event (parse);

      if (ret == GST_RIFF_EOS)
	return ret;
    }
  } while (got_bytes != sizeof (gst_riff_chunk));

  *id = chunk->id;

  switch (chunk->id) {
    case GST_RIFF_TAG_RIFF:
    case GST_RIFF_TAG_LIST:
      skipsize = sizeof (gst_riff_list);
      break;
    default:
      skipsize = (chunk->size + 8 + 1) & ~1;
      break;
  }

  do {
    got_bytes = gst_bytestream_read (bs, buf, skipsize);
    if (got_bytes < skipsize) {
      GstRiffReturn ret;
      
      ret = gst_riff_parse_handle_sink_event (parse);

      if (ret == GST_RIFF_EOS)
	return ret;
    }
  } while (got_bytes != skipsize);

  return GST_RIFF_OK;
}