summaryrefslogtreecommitdiff
path: root/src/demuxers/demux_asf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers/demux_asf.c')
-rw-r--r--src/demuxers/demux_asf.c273
1 files changed, 105 insertions, 168 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 65838138f..57624aa15 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -15,9 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * $Id: demux_asf.c,v 1.194 2007/03/09 23:18:19 dgp85 Exp $
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* demultiplexer for asf streams
*
@@ -47,12 +45,12 @@
/*
#define LOG
*/
-#include "xine_internal.h"
-#include "demux.h"
-#include "xineutils.h"
+#include <xine/xine_internal.h>
+#include <xine/demux.h>
+#include <xine/xineutils.h>
#include "bswap.h"
#include "asfheader.h"
-#include "xmlparser.h"
+#include <xine/xmlparser.h>
#define CODEC_TYPE_AUDIO 0
#define CODEC_TYPE_VIDEO 1
@@ -201,7 +199,7 @@ static uint16_t get_le16 (demux_asf_t *this) {
this->status = DEMUX_FINISHED;
}
- return LE_16(buf);
+ return _X_LE_16(buf);
}
static uint32_t get_le32 (demux_asf_t *this) {
@@ -218,7 +216,7 @@ static uint32_t get_le32 (demux_asf_t *this) {
this->status = DEMUX_FINISHED;
}
- return LE_32(buf);
+ return _X_LE_32(buf);
}
static uint64_t get_le64 (demux_asf_t *this) {
@@ -233,7 +231,7 @@ static uint64_t get_le64 (demux_asf_t *this) {
this->status = DEMUX_FINISHED;
}
- return LE_64(buf);
+ return _X_LE_64(buf);
}
static int get_guid_id (demux_asf_t *this, GUID *g) {
@@ -378,7 +376,7 @@ static void asf_send_video_header (demux_asf_t *this, int stream) {
static int asf_read_header (demux_asf_t *this) {
int i;
uint64_t asf_header_len;
- char *asf_header_buffer = NULL;
+ uint8_t *asf_header_buffer = NULL;
asf_header_len = get_le64(this);
asf_header_buffer = alloca(asf_header_len);
@@ -483,10 +481,10 @@ static int asf_read_header (demux_asf_t *this) {
uint16_t bmiheader_size;
xine_bmiheader *bmiheader;
- width = LE_32(asf_stream->private_data);
- height = LE_32(asf_stream->private_data + 4);
+ width = _X_LE_32(asf_stream->private_data);
+ height = _X_LE_32(asf_stream->private_data + 4);
/* there is one unknown byte between height and the bmiheader size */
- bmiheader_size = LE_16(asf_stream->private_data + 9);
+ bmiheader_size = _X_LE_16(asf_stream->private_data + 9);
/* FIXME: bmiheader_size must be >= sizeof(xine_bmiheader) */
@@ -516,7 +514,7 @@ static int asf_read_header (demux_asf_t *this) {
lprintf ("palette_count: %d\n", demux_stream->palette_count);
if (demux_stream->palette_count > 256) {
- lprintf ("number of colors exceeded 256 (%d)", demux_stream->palette_count);
+ lprintf ("number of colours exceeded 256 (%d)", demux_stream->palette_count);
demux_stream->palette_count = 256;
}
if ((asf_stream->private_data_length - sizeof(xine_bmiheader) - 11) >= (demux_stream->palette_count * 4)) {
@@ -614,14 +612,14 @@ static int demux_asf_send_headers_common (demux_asf_t *this) {
}
static void asf_reorder(demux_asf_t *this, uint8_t *src, int len){
- uint8_t *dst = malloc(len);
+ uint8_t dst[len];
uint8_t *s2 = src;
int i = 0, x, y;
while(len-i >= this->reorder_h * this->reorder_w*this->reorder_b){
for(x = 0; x < this->reorder_w; x++)
for(y = 0; y < this->reorder_h; y++){
- memcpy(dst + i, s2 + (y * this->reorder_w+x) * this->reorder_b,
+ memcpy(&dst[i], s2 + (y * this->reorder_w+x) * this->reorder_b,
this->reorder_b);
i += this->reorder_b;
}
@@ -629,7 +627,6 @@ static void asf_reorder(demux_asf_t *this, uint8_t *src, int len){
}
xine_fast_memcpy(src,dst,i);
- free(dst);
}
/* redefine abs as macro to handle 64-bit diffs.
@@ -725,6 +722,9 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str
buf->size = bufsize;
timestamp = 0;
+ if (stream->frag_offset == 0)
+ buf->decoder_flags |= BUF_FLAG_FRAME_START;
+
stream->frag_offset += bufsize;
frag_len -= bufsize;
@@ -735,10 +735,6 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str
else
check_newpts (this, buf->pts, PTS_AUDIO, package_done);
-
- if (frag_offset == 0)
- buf->decoder_flags |= BUF_FLAG_FRAME_START;
-
/* test if whole packet read */
if (package_done) {
buf->decoder_flags |= BUF_FLAG_FRAME_END;
@@ -935,9 +931,9 @@ static int asf_parse_packet_ecd(demux_asf_t *this, uint32_t *p_hdr_size) {
return 1;
}
*p_hdr_size += 15;
- guid->Data1 = LE_32(buf);
- guid->Data2 = LE_16(buf + 4);
- guid->Data3 = LE_16(buf + 6);
+ guid->Data1 = _X_LE_32(buf);
+ guid->Data2 = _X_LE_16(buf + 4);
+ guid->Data3 = _X_LE_16(buf + 6);
if (get_guid_id(this, guid) == GUID_ASF_HEADER) {
lprintf("new asf header detected\n");
_x_demux_control_end(this->stream, 0);
@@ -1538,108 +1534,90 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) {
ENTRYREF, MOREINFO, PARAM, REPEAT, TITLE
*/
- const char *version = xml_parser_get_property (xml_tree, "VERSION");
+ const char *base_href = NULL;
- if (version) {
- int version_major, version_minor = 0;
+ for (asx_entry = xml_tree->child; asx_entry; asx_entry = asx_entry->next)
+ {
+ const char *ref_base_href = base_href;
- if((sscanf (version, "%d.%d", &version_major, &version_minor) == 2 ||
- sscanf (version, "%d", &version_major) == 1) &&
- (version_major == 3 && version_minor == 0))
+ if (!strcasecmp (asx_entry->name, "ENTRY"))
{
- const char *base_href = NULL;
+ /* Attributes: CLIENTSKIP, SKIPIFREF
+ * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION,
+ ENDMARKER, MOREINFO, PARAM, REF, STARTMARKER,
+ STARTTIME, TITLE
+ */
+ const char *href = NULL;
+ const char *title = NULL;
+ uint32_t start_time = (uint32_t)-1;
+ uint32_t duration = (uint32_t)-1;
- for (asx_entry = xml_tree->child; asx_entry; asx_entry = asx_entry->next)
+ for (asx_ref = asx_entry->child; asx_ref; asx_ref = asx_ref->next)
{
- const char *ref_base_href = base_href;
-
- if (!strcasecmp (asx_entry->name, "ENTRY"))
+ if (!strcasecmp(asx_ref->name, "REF"))
{
- /* Attributes: CLIENTSKIP, SKIPIFREF
- * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION,
- ENDMARKER, MOREINFO, PARAM, REF, STARTMARKER,
- STARTTIME, TITLE
+ xml_node_t *asx_sub;
+ /* Attributes: HREF
+ * Child elements: DURATION, ENDMARKER, STARTMARKER, STARTTIME
+ */
+
+ /* FIXME: multiple REFs => alternative streams
+ * (and per-ref start times and durations?).
+ * Just the one title, though.
*/
- const char *href = NULL;
- const char *title = NULL;
- uint32_t start_time = (uint32_t)-1;
- uint32_t duration = (uint32_t)-1;
+ href = xml_parser_get_property (asx_ref, "HREF");
- for (asx_ref = asx_entry->child; asx_ref; asx_ref = asx_ref->next)
+ for (asx_sub = asx_ref->child; asx_sub; asx_sub = asx_sub->next)
{
- if (!strcasecmp(asx_ref->name, "REF"))
- {
- xml_node_t *asx_sub;
- /* Attributes: HREF
- * Child elements: DURATION, ENDMARKER, STARTMARKER, STARTTIME
- */
-
- /* FIXME: multiple REFs => alternative streams
- * (and per-ref start times and durations?).
- * Just the one title, though.
- */
- href = xml_parser_get_property (asx_ref, "HREF");
-
- for (asx_sub = asx_ref->child; asx_sub; asx_sub = asx_sub->next)
- {
- if (!strcasecmp (asx_sub->name, "STARTTIME"))
- start_time = asx_get_time_value (asx_sub);
- else if (!strcasecmp (asx_sub->name, "DURATION"))
- duration = asx_get_time_value (asx_sub);
- }
- }
-
- else if (!strcasecmp (asx_ref->name, "TITLE"))
- {
- if (!title)
- title = asx_ref->data;
- }
-
- else if (!strcasecmp (asx_ref->name, "STARTTIME"))
- {
- if (start_time == (uint32_t)-1)
- start_time = asx_get_time_value (asx_ref);
- }
-
- else if (!strcasecmp (asx_ref->name, "DURATION"))
- {
- if (duration == (uint32_t)-1)
- duration = asx_get_time_value (asx_ref);
- }
-
- else if (!strcasecmp (asx_ref->name, "BASE"))
- /* Attributes: HREF */
- ref_base_href = xml_parser_get_property (asx_entry, "HREF");
+ if (!strcasecmp (asx_sub->name, "STARTTIME"))
+ start_time = asx_get_time_value (asx_sub);
+ else if (!strcasecmp (asx_sub->name, "DURATION"))
+ duration = asx_get_time_value (asx_sub);
}
+ }
- /* FIXME: prepend ref_base_href to href */
- if (href && *href)
- _x_demux_send_mrl_reference (this->stream, 0, href, title,
- start_time == (uint32_t)-1 ? 0 : start_time,
- duration == (uint32_t)-1 ? -1 : duration);
+ else if (!strcasecmp (asx_ref->name, "TITLE"))
+ {
+ if (!title)
+ title = asx_ref->data;
+ }
+
+ else if (!strcasecmp (asx_ref->name, "STARTTIME"))
+ {
+ if (start_time == (uint32_t)-1)
+ start_time = asx_get_time_value (asx_ref);
}
- else if (!strcasecmp (asx_entry->name, "ENTRYREF"))
+ else if (!strcasecmp (asx_ref->name, "DURATION"))
{
- /* Attributes: HREF, CLIENTBIND */
- const char *href = xml_parser_get_property (asx_entry, "HREF");
- if (href && *href)
- _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, -1);
+ if (duration == (uint32_t)-1)
+ duration = asx_get_time_value (asx_ref);
}
- else if (!strcasecmp (asx_entry->name, "BASE"))
+ else if (!strcasecmp (asx_ref->name, "BASE"))
/* Attributes: HREF */
- base_href = xml_parser_get_property (asx_entry, "HREF");
+ ref_base_href = xml_parser_get_property (asx_entry, "HREF");
}
+
+ /* FIXME: prepend ref_base_href to href */
+ if (href && *href)
+ _x_demux_send_mrl_reference (this->stream, 0, href, title,
+ start_time == (uint32_t)-1 ? 0 : start_time,
+ duration == (uint32_t)-1 ? -1 : duration);
}
- else
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _("demux_asf: Wrong ASX version: %s\n"), version);
-
+
+ else if (!strcasecmp (asx_entry->name, "ENTRYREF"))
+ {
+ /* Attributes: HREF, CLIENTBIND */
+ const char *href = xml_parser_get_property (asx_entry, "HREF");
+ if (href && *href)
+ _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, -1);
+ }
+
+ else if (!strcasecmp (asx_entry->name, "BASE"))
+ /* Attributes: HREF */
+ base_href = xml_parser_get_property (asx_entry, "HREF");
}
- else
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_asf: Unable to find VERSION tag from ASX.\n");
}
else
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -1682,7 +1660,7 @@ static int demux_asf_send_chunk (demux_plugin_t *this_gen) {
default:
{
- int header_size = 0;
+ uint32_t header_size = 0;
if (asf_parse_packet_align(this)) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_align failed\n");
@@ -1868,7 +1846,7 @@ static int demux_asf_seek (demux_plugin_t *this_gen,
start_pos -= (start_pos - this->first_packet_pos) % this->packet_size;
while ((start_pos >= this->first_packet_pos) && (state != 5)) {
- int header_size;
+ uint32_t header_size;
/* seek to the beginning of the previous packet */
lprintf ("demux_asf_seek: seek back\n");
@@ -2042,10 +2020,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
!strstr(buf,"ASX") &&
strncmp(buf,"[Reference]", 11) &&
strncmp(buf,"ASF ", 4) &&
- ((buf[0] != 0x30)
- || (buf[1] != 0x26)
- || (buf[2] != 0xb2)
- || (buf[3] != 0x75)))
+ memcmp(buf, "\x30\x26\xB2\x75", 4)
+ )
return NULL;
}
@@ -2053,23 +2029,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
break;
- case METHOD_BY_EXTENSION: {
- const char *const mrl = input->get_mrl (input);
- const char *const ending = strrchr (mrl, '.');
-
- if (!ending)
- return NULL;
-
- if (strncasecmp(ending, ".asf", 4) &&
- strncasecmp(ending, ".wmv", 4) &&
- strncasecmp(ending, ".wma", 4) ) {
- return NULL;
- }
-
- lprintf ("extension accepted.\n");
- }
- break;
-
+ case METHOD_BY_MRL:
case METHOD_EXPLICIT:
break;
@@ -2118,38 +2078,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
return &this->demux_plugin;
}
-static const char *get_description (demux_class_t *this_gen) {
- return "ASF demux plugin";
-}
-
-static const char *get_identifier (demux_class_t *this_gen) {
- return "ASF";
-}
-
-static const char *get_extensions (demux_class_t *this_gen) {
- /* asx, wvx, wax are metafile or playlist */
- return "asf wmv wma asx wvx wax";
-}
-
-static const char *get_mimetypes (demux_class_t *this_gen) {
-
- return "video/x-ms-asf: asf: ASF stream;"
- "video/x-ms-wmv: wmv: Windows Media Video;"
- "audio/x-ms-wma: wma: Windows Media Audio;"
- "application/vnd.ms-asf: asf: ASF stream;"
- "application/x-mplayer2: asf,asx,asp: mplayer2;"
- "video/x-ms-asf-plugin: asf,asx,asp: mms animation;"
- "video/x-ms-wvx: wvx: wmv metafile;"
- "video/x-ms-wax: wva: wma metafile;";
-}
-
-static void class_dispose (demux_class_t *this_gen) {
-
- demux_asf_class_t *this = (demux_asf_class_t *) this_gen;
-
- free (this);
-}
-
static void *init_class (xine_t *xine, void *data) {
demux_asf_class_t *this;
@@ -2159,11 +2087,20 @@ static void *init_class (xine_t *xine, void *data) {
this->xine = xine;
this->demux_class.open_plugin = open_plugin;
- this->demux_class.get_description = get_description;
- this->demux_class.get_identifier = get_identifier;
- this->demux_class.get_mimetypes = get_mimetypes;
- this->demux_class.get_extensions = get_extensions;
- this->demux_class.dispose = class_dispose;
+ this->demux_class.description = N_("ASF demux plugin");
+ this->demux_class.identifier = "ASF";
+ this->demux_class.mimetypes =
+ "video/x-ms-asf: asf: ASF stream;"
+ "video/x-ms-wmv: wmv: Windows Media Video;"
+ "audio/x-ms-wma: wma: Windows Media Audio;"
+ "application/vnd.ms-asf: asf: ASF stream;"
+ "application/x-mplayer2: asf,asx,asp: mplayer2;"
+ "video/x-ms-asf-plugin: asf,asx,asp: mms animation;"
+ "video/x-ms-wvx: wvx: wmv metafile;"
+ "video/x-ms-wax: wva: wma metafile;";
+ /* asx, wvx, wax are metafile or playlist */
+ this->demux_class.extensions = "asf wmv wma asx wvx wax";
+ this->demux_class.dispose = default_demux_class_dispose;
return this;
}
@@ -2178,6 +2115,6 @@ static const demuxer_info_t demux_info_asf = {
const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 26, "asf", XINE_VERSION_CODE, &demux_info_asf, init_class },
+ { PLUGIN_DEMUX, 27, "asf", XINE_VERSION_CODE, &demux_info_asf, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};