Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / sys / qtwrapper / imagedescription.c
1 /*
2  * GStreamer QuickTime video decoder codecs wrapper
3  * Copyright <2006, 2007> Fluendo <gstreamer@fluendo.com>
4  * Copyright <2006, 2007> Pioneers of the Inevitable <songbird@songbirdnest.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Alternatively, the contents of this file may be used under the
25  * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
26  * which case the following provisions apply instead of the ones
27  * mentioned above:
28  *
29  * This library is free software; you can redistribute it and/or
30  * modify it under the terms of the GNU Library General Public
31  * License as published by the Free Software Foundation; either
32  * version 2 of the License, or (at your option) any later version.
33  *
34  * This library is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
37  * Library General Public License for more details.
38  *
39  * You should have received a copy of the GNU Library General Public
40  * License along with this library; if not, write to the
41  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
42  * Boston, MA 02111-1307, USA.
43  */
44
45 #include <string.h>
46
47 #include "imagedescription.h"
48
49 static ImageDescription *
50 image_description_for_avc1 (GstBuffer * buf)
51 {
52   ImageDescription *desc = NULL;
53   guint8 *pos;
54
55   desc = g_malloc0 (sizeof (ImageDescription) + GST_BUFFER_SIZE (buf) + 8);
56   pos = (guint8 *) desc + sizeof (ImageDescription);
57
58   desc->idSize = sizeof (ImageDescription) + GST_BUFFER_SIZE (buf) + 8;
59   /* write size in Big-Endian */
60   GST_WRITE_UINT32_BE (pos, GST_BUFFER_SIZE (buf) + 8);
61   GST_WRITE_UINT32_LE (pos + 4, QT_MAKE_FOURCC_BE ('a', 'v', 'c', 'C'));
62   g_memmove (pos + 8, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
63
64   return desc;
65 }
66
67 /* image_description_for_mp4v
68  *
69  * mpeg4 video has an 'esds' atom as extension for the ImageDescription.
70  * It is meant to contain the ES Description.
71  * We here create a fake one.
72  */
73
74 static ImageDescription *
75 image_description_for_mp4v (GstBuffer * buf)
76 {
77   ImageDescription *desc = NULL;
78   guint32 offset = sizeof (ImageDescription);
79   guint8 *location;
80
81   GST_LOG ("buf %p , size:%d", buf, GST_BUFFER_SIZE (buf));
82
83   /* this image description contains:
84    *  ImageDescription  sizeof(ImageDescription)
85    *  esds atom         34 bytes
86    *  buffer            GST_BUFFER_SIZE (buf)
87    *  ending            3 bytes
88    */
89
90   desc = g_malloc0 (offset + 37 + GST_BUFFER_SIZE (buf));
91   desc->idSize = offset + 37 + GST_BUFFER_SIZE (buf);
92
93   location = (guint8 *) desc + offset;
94
95   /* Fill in ESDS */
96   /*  size */
97   GST_WRITE_UINT32_BE (location, 37 + GST_BUFFER_SIZE (buf));
98   /*  atom */
99   GST_WRITE_UINT32_LE (location + 4, GST_MAKE_FOURCC ('e', 's', 'd', 's'));
100   /*  version + flags */
101   QT_WRITE_UINT32 (location + 8, 0);
102   /*  tag */
103   QT_WRITE_UINT8 (location + 12, 0x3);
104   /*  size (buffsize + 23) */
105   QT_WRITE_UINT8 (location + 13, GST_BUFFER_SIZE (buf) + 23);
106   /*  ESID */
107   QT_WRITE_UINT16 (location + 14, 0);
108   /*  priority */
109   QT_WRITE_UINT8 (location + 16, 0);
110   /*  tag */
111   QT_WRITE_UINT8 (location + 17, 0x4);
112   /*  size (buffsize + 8) */
113   QT_WRITE_UINT8 (location + 18, GST_BUFFER_SIZE (buf) + 15);
114   /*  object type */
115   QT_WRITE_UINT8 (location + 19, 0x20);
116   /*  stream type */
117   QT_WRITE_UINT8 (location + 20, 0x11);
118   /*  buffersize db */
119   QT_WRITE_UINT24 (location + 21, 13640);
120   /*  max bitrate */
121   QT_WRITE_UINT32 (location + 24, 1849648);
122   /*  avg bitrate */
123   QT_WRITE_UINT32 (location + 28, 918191);
124   /*  tag */
125   QT_WRITE_UINT8 (location + 32, 0x05);
126   /*  size */
127   QT_WRITE_UINT8 (location + 33, GST_BUFFER_SIZE (buf));
128   /*  codec data */
129   g_memmove (location + 34, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
130   /*  end */
131   QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf), 0x06);
132   QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf) + 1, 0x01);
133   QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf) + 2, 0x02);
134
135   return desc;
136 }
137
138 static ImageDescription *
139 image_description_from_stsd_buffer (GstBuffer * buf)
140 {
141   ImageDescription *desc = NULL;
142   guint8 *content;
143   guint size;
144   gint imds;
145
146   GST_LOG ("buffer %p, size:%u", buf, GST_BUFFER_SIZE (buf));
147
148   /* The buffer contains a full atom, we only need the contents */
149   /* This buffer has data in big-endian, we need to read it as such.
150    * except for the fourcc which are ALWAYS big-endian. */
151   content = GST_BUFFER_DATA (buf) + 16;
152   size = GST_BUFFER_SIZE (buf) - 16;
153
154 #if DEBUG_DUMP
155   GST_LOG ("incoming data in big-endian");
156   gst_util_dump_mem (content, size);
157 #endif
158
159   desc = g_malloc0 (size);
160   desc->idSize = size;
161   desc->cType = GST_READ_UINT32_BE (content + 4);
162   desc->version = QT_UINT16 (content + 16);
163   desc->revisionLevel = QT_UINT16 (content + 18);
164   desc->vendor = GST_READ_UINT32_BE (content + 20);
165   desc->temporalQuality = QT_UINT32 (content + 24);
166   desc->spatialQuality = QT_UINT32 (content + 24);
167   desc->dataSize = QT_UINT32 (content + 44);
168   desc->frameCount = QT_UINT16 (content + 48);
169   desc->depth = QT_UINT16 (content + 82);
170   desc->clutID = QT_UINT16 (content + 84);
171
172   imds = 86;                    /* sizeof (ImageDescription); */
173
174   if (desc->idSize > imds) {
175     GST_LOG ("Copying %d bytes from %p to %p",
176         size - imds, content + imds, desc + imds);
177     memcpy ((guint8 *) desc + imds, (guint8 *) content + imds, size - imds);
178   }
179 #if DEBUG_DUMP
180   GST_LOG ("outgoing data in machine-endian");
181   dump_image_description (desc);
182 #endif
183
184   return desc;
185 }
186
187 ImageDescription *
188 image_description_from_codec_data (GstBuffer * buf, guint32 codectype)
189 {
190   ImageDescription *desc = NULL;
191
192   GST_LOG ("codectype:%" GST_FOURCC_FORMAT " buf:%p",
193       GST_FOURCC_ARGS (codectype), buf);
194
195   if ((GST_BUFFER_SIZE (buf) == GST_READ_UINT32_BE (GST_BUFFER_DATA (buf))) &&
196       (QT_MAKE_FOURCC_LE ('s', 't', 's',
197               'd') == GST_READ_UINT32_BE (GST_BUFFER_DATA (buf) + 4))) {
198     /* We have the full stsd (ImageDescription) in our codec_data */
199     desc = image_description_from_stsd_buffer (buf);
200   } else {
201     switch (codectype) {
202       case QT_MAKE_FOURCC_LE ('m', 'p', '4', 'v'):
203         desc = image_description_for_mp4v (buf);
204         break;
205       case QT_MAKE_FOURCC_LE ('a', 'v', 'c', '1'):
206         desc = image_description_for_avc1 (buf);
207         break;
208       default:
209         GST_WARNING ("Format not handled !");
210     }
211   }
212   return desc;
213 }