summaryrefslogtreecommitdiff
path: root/src/demuxers/demux_qt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers/demux_qt.c')
-rw-r--r--src/demuxers/demux_qt.c699
1 files changed, 363 insertions, 336 deletions
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index 4144f3049..6b2aa5eea 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -15,7 +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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* Quicktime File Demuxer by Mike Melanson (melanson@pcisys.net)
* based on a Quicktime parsing experiment entitled 'lazyqt'
@@ -29,9 +29,6 @@
* parse_trak_atom
* build_frame_table
* free_qt_info
- *
- * $Id: demux_qt.c,v 1.214 2007/01/19 01:05:24 dgp85 Exp $
- *
*/
#ifdef HAVE_CONFIG_H
@@ -46,10 +43,10 @@
#include <ctype.h>
#include <zlib.h>
-#include "xine_internal.h"
-#include "xineutils.h"
-#include "demux.h"
-#include "buffer.h"
+#include <xine/xine_internal.h>
+#include <xine/xineutils.h>
+#include <xine/demux.h>
+#include <xine/buffer.h>
#include "bswap.h"
#include "qtpalette.h"
@@ -110,6 +107,8 @@ typedef unsigned int qt_atom;
#define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a')
#define META_ATOM QT_ATOM('m', 'e', 't', 'a')
+#define HDLR_ATOM QT_ATOM('h', 'd', 'l', 'r')
+#define ILST_ATOM QT_ATOM('i', 'l', 's', 't')
#define NAM_ATOM QT_ATOM(0xA9, 'n', 'a', 'm')
#define CPY_ATOM QT_ATOM(0xA9, 'c', 'p', 'y')
#define DES_ATOM QT_ATOM(0xA9, 'd', 'e', 's')
@@ -121,6 +120,7 @@ typedef unsigned int qt_atom;
#define WRT_ATOM QT_ATOM(0xA9, 'w', 'r', 't')
#define DAY_ATOM QT_ATOM(0xA9, 'd', 'a', 'y')
+#define RMRA_ATOM QT_ATOM('r', 'm', 'r', 'a')
#define RMDA_ATOM QT_ATOM('r', 'm', 'd', 'a')
#define RDRF_ATOM QT_ATOM('r', 'd', 'r', 'f')
#define RMDR_ATOM QT_ATOM('r', 'm', 'd', 'r')
@@ -135,8 +135,10 @@ typedef unsigned int qt_atom;
#define MAX_PTS_DIFF 100000
-/* network bandwidth, cribbed from src/input/input_mms.c */
-const int64_t bandwidths[]={14400,19200,28800,33600,34430,57600,
+/**
+ * @brief Network bandwidth, cribbed from src/input/input_mms.c
+ */
+static const int64_t bandwidths[]={14400,19200,28800,33600,34430,57600,
115200,262200,393216,524300,1544000,10485800};
/* these are things that can go wrong */
@@ -186,7 +188,7 @@ typedef struct {
} time_to_sample_table_t;
typedef struct {
- unsigned char *url;
+ char *url;
int64_t data_rate;
int qtim_version;
} reference_t;
@@ -403,6 +405,10 @@ typedef struct {
* demuxer is sending off to the audio decoder */
#define DEBUG_AUDIO_DEMUX 0
+/* define DEBUG_META_LOAD as 1 to see details about the metadata chunks the
+ * demuxer is reading from the file */
+#define DEBUG_META_LOAD 0
+
/* Define DEBUG_DUMP_MOOV as 1 to dump the raw moov atom to disk. This is
* particularly useful in debugging a file with a compressed moov (cmov)
* atom. The atom will be dumped to the filename specified as
@@ -410,38 +416,40 @@ typedef struct {
#define DEBUG_DUMP_MOOV 0
#define RAW_MOOV_FILENAME "moovatom.raw"
-#ifndef __GNUC__
-#define __attribute__(x)
-#endif
-
#if DEBUG_ATOM_LOAD
#define debug_atom_load printf
#else
-static inline void __attribute__((format (printf, 1, 2))) debug_atom_load(const char *format, ...) {}
+static inline void XINE_FORMAT_PRINTF(1, 2) debug_atom_load(const char *format, ...) {}
#endif
#if DEBUG_EDIT_LIST
#define debug_edit_list printf
#else
-static inline void __attribute__((format (printf, 1, 2))) debug_edit_list(const char *format, ...) {}
+static inline void XINE_FORMAT_PRINTF(1, 2) debug_edit_list(const char *format, ...) {}
#endif
#if DEBUG_FRAME_TABLE
#define debug_frame_table printf
#else
-static inline void __attribute__((format (printf, 1, 2))) debug_frame_table(const char *format, ...) {}
+static inline void XINE_FORMAT_PRINTF(1, 2) debug_frame_table(const char *format, ...) {}
#endif
#if DEBUG_VIDEO_DEMUX
#define debug_video_demux printf
#else
-static inline void __attribute__((format (printf, 1, 2))) debug_video_demux(const char *format, ...) {}
+static inline void XINE_FORMAT_PRINTF(1, 2) debug_video_demux(const char *format, ...) {}
#endif
#if DEBUG_AUDIO_DEMUX
#define debug_audio_demux printf
#else
-static inline void __attribute__((format (printf, 1, 2))) debug_audio_demux(const char *format, ...) {}
+static inline void XINE_FORMAT_PRINTF(1, 2) debug_audio_demux(const char *format, ...) {}
+#endif
+
+#if DEBUG_META_LOAD
+#define debug_meta_load printf
+#else
+static inline void XINE_FORMAT_PRINTF(1, 2) debug_meta_load(const char *format, ...) {}
#endif
static inline void dump_moov_atom(unsigned char *moov_atom, int moov_atom_size) {
@@ -500,8 +508,8 @@ static void find_moov_atom(input_plugin_t *input, off_t *moov_offset,
ATOM_PREAMBLE_SIZE)
break;
- atom_size = BE_32(&atom_preamble[0]);
- atom = BE_32(&atom_preamble[4]);
+ atom_size = _X_BE_32(&atom_preamble[0]);
+ atom = _X_BE_32(&atom_preamble[4]);
/* Special case alert: 'free' atoms sometimes masquerade as 'moov'
* atoms. If this is a free atom, check for 'cmov' or 'mvhd' immediately
@@ -515,8 +523,8 @@ static void find_moov_atom(input_plugin_t *input, off_t *moov_offset,
/* if there is a cmov, qualify this free atom as the 'moov' atom
* if no actual 'moov' atom is found. */
- if ((BE_32(&atom_preamble[4]) == CMOV_ATOM) ||
- (BE_32(&atom_preamble[4]) == MVHD_ATOM)) {
+ if ((_X_BE_32(&atom_preamble[4]) == CMOV_ATOM) ||
+ (_X_BE_32(&atom_preamble[4]) == MVHD_ATOM)) {
/* pos = current pos minus 2 atom preambles */
free_moov_offset = input->get_current_pos(input) - ATOM_PREAMBLE_SIZE * 2;
free_moov_size = atom_size;
@@ -560,9 +568,9 @@ static void find_moov_atom(input_plugin_t *input, off_t *moov_offset,
ATOM_PREAMBLE_SIZE)
break;
- atom_size = BE_32(&atom_preamble[0]);
+ atom_size = _X_BE_32(&atom_preamble[0]);
atom_size <<= 32;
- atom_size |= BE_32(&atom_preamble[4]);
+ atom_size |= _X_BE_32(&atom_preamble[4]);
atom_size -= ATOM_PREAMBLE_SIZE * 2;
} else
atom_size -= ATOM_PREAMBLE_SIZE;
@@ -643,8 +651,7 @@ static void free_qt_info(qt_info *info) {
for (j = 0; j < info->traks[i].stsd_atoms_count; j++) {
if (info->traks[i].type == MEDIA_AUDIO) {
free(info->traks[i].stsd_atoms[j].audio.properties_atom);
- if (info->traks[i].stsd_atoms[j].audio.wave)
- free(info->traks[i].stsd_atoms[j].audio.wave);
+ free(info->traks[i].stsd_atoms[j].audio.wave);
} else if (info->traks[i].type == MEDIA_VIDEO)
free(info->traks[i].stsd_atoms[j].video.properties_atom);
}
@@ -678,34 +685,28 @@ static int is_qt_file(input_plugin_t *qt_file) {
off_t moov_atom_offset = -1;
int64_t moov_atom_size = -1;
int i;
- unsigned char atom_preamble[ATOM_PREAMBLE_SIZE];
- unsigned char preview[MAX_PREVIEW_SIZE];
int len;
/* if the input is non-seekable, be much more stringent about qualifying
* a QT file: In this case, the moov must be the first atom in the file */
if ((qt_file->get_capabilities(qt_file) & INPUT_CAP_SEEKABLE) == 0) {
- memset (&preview, 0, MAX_PREVIEW_SIZE);
+ unsigned char preview[MAX_PREVIEW_SIZE] = { 0, };
len = qt_file->get_optional_data(qt_file, preview, INPUT_OPTIONAL_DATA_PREVIEW);
- if (BE_32(&preview[4]) == MOOV_ATOM)
+ if (_X_BE_32(&preview[4]) == MOOV_ATOM)
return 1;
else {
- if (BE_32(&preview[4]) == FTYP_ATOM) {
- /* show some lenience if the first atom is 'ftyp'; the second atom
- * could be 'moov' */
- moov_atom_size = BE_32(&preview[0]);
- /* compute the size of the current atom plus the preamble of the
- * next atom; if the size is within the range on the preview buffer
- * then the next atom's preamble is in the preview buffer */
- i = moov_atom_size + ATOM_PREAMBLE_SIZE;
- if (i >= MAX_PREVIEW_SIZE)
- return 0;
- if (BE_32(&preview[i - 4]) == MOOV_ATOM)
- return 1;
- else
- return 0;
- } else
- return 0;
+ if (_X_BE_32(&preview[4]) != FTYP_ATOM)
+ return 0;
+
+ /* show some lenience if the first atom is 'ftyp'; the second atom
+ * could be 'moov'
+ * compute the size of the current atom plus the preamble of the
+ * next atom; if the size is within the range on the preview buffer
+ * then the next atom's preamble is in the preview buffer */
+ uint64_t ftyp_atom_size = _X_BE_32(&preview[0]) + ATOM_PREAMBLE_SIZE;
+ if (ftyp_atom_size >= MAX_PREVIEW_SIZE)
+ return 0;
+ return _X_BE_32(&preview[ftyp_atom_size - 4]) == MOOV_ATOM;
}
}
@@ -713,6 +714,7 @@ static int is_qt_file(input_plugin_t *qt_file) {
if (moov_atom_offset == -1) {
return 0;
} else {
+ unsigned char atom_preamble[ATOM_PREAMBLE_SIZE];
/* check that the next atom in the chunk contains alphanumeric
* characters in the atom type field; if not, disqualify the file
* as a QT file */
@@ -728,52 +730,116 @@ static int is_qt_file(input_plugin_t *qt_file) {
}
}
+static char *parse_data_atom(const uint8_t *data_atom) {
+ const uint32_t data_atom_size = _X_BE_32(&data_atom[0]);
+
+ static const int data_atom_max_version = 0;
+ const int data_atom_version = data_atom[8];
+
+ const size_t alloc_size = data_atom_size - 8 + 1;
+ char *alloc_str = NULL;
+
+ if ( data_atom_version > data_atom_max_version ) {
+ debug_meta_load("demux_qt: version %d for data atom is higher than the highest supported version (%d)\n",
+ data_atom_version, data_atom_max_version);
+ return NULL;
+ }
+
+ alloc_str = xine_xmalloc(alloc_size);
+ xine_fast_memcpy(alloc_str, &data_atom[16], alloc_size-1);
+ alloc_str[alloc_size-1] = '\0';
+
+ debug_meta_load("demux_qt: got a string of size %zd (%s)\n", alloc_size, alloc_str);
+
+ return alloc_str;
+}
+
/* parse out a meta data atom */
static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) {
- int i;
- unsigned int meta_atom_size = BE_32(&meta_atom[0]);
- qt_atom current_atom;
- int string_size;
-
- for (i = 0; i < meta_atom_size - 4; i++) {
- current_atom = BE_32(&meta_atom[i]);
-
- if (current_atom == ART_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->artist = xine_xmalloc(string_size);
- strncpy(info->artist, &meta_atom[i + 20], string_size - 1);
- info->artist[string_size - 1] = 0;
- } else if (current_atom == NAM_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->name = xine_xmalloc(string_size);
- strncpy(info->name, &meta_atom[i + 20], string_size - 1);
- info->name[string_size - 1] = 0;
- } else if (current_atom == ALB_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->album = xine_xmalloc(string_size);
- strncpy(info->album, &meta_atom[i + 20], string_size - 1);
- info->album[string_size - 1] = 0;
- } else if (current_atom == GEN_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->genre = xine_xmalloc(string_size);
- strncpy(info->genre, &meta_atom[i + 20], string_size - 1);
- info->genre[string_size - 1] = 0;
- } else if (current_atom == TOO_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->comment = xine_xmalloc(string_size);
- strncpy(info->comment, &meta_atom[i + 20], string_size - 1);
- info->comment[string_size - 1] = 0;
- } else if (current_atom == WRT_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->composer = xine_xmalloc(string_size);
- strncpy(info->composer, &meta_atom[i + 20], string_size - 1);
- info->composer[string_size - 1] = 0;
- } else if (current_atom == DAY_ATOM) {
- string_size = BE_32(&meta_atom[i + 4]) - 16 + 1;
- info->year = xine_xmalloc(string_size);
- strncpy(info->year, &meta_atom[i + 20], string_size - 1);
- info->year[string_size - 1] = 0;
+ static const uint32_t meta_atom_preamble_size = 12;
+
+ const uint32_t meta_atom_size = _X_BE_32(&meta_atom[0]);
+
+ static const int meta_atom_max_version = 0;
+ const int meta_atom_version = meta_atom[8];
+ /* const uint32_t flags = _X_BE_24(&meta_atom[9]); */
+
+ uint32_t i = meta_atom_preamble_size;
+
+ if ( meta_atom_version > meta_atom_max_version ) {
+ debug_meta_load("demux_qt: version %d for meta atom is higher than the highest supported version (%d)\n",
+ meta_atom_version, meta_atom_max_version);
+ return;
+ }
+
+ while ( i < meta_atom_size ) {
+ const uint8_t *const current_atom = &meta_atom[i];
+ const qt_atom current_atom_code = _X_BE_32(&current_atom[4]);
+ const uint32_t current_atom_size = _X_BE_32(&current_atom[0]);
+ uint32_t handler_type = 0;
+
+ switch (current_atom_code) {
+ case HDLR_ATOM: {
+ static const int hdlr_atom_max_version = 0;
+ const int hdlr_atom_version = current_atom[8];
+
+ /* const uint32_t hdlr_atom_flags = _X_BE_24(&current_atom[9]); */
+
+ if ( hdlr_atom_version > hdlr_atom_max_version ) {
+ debug_meta_load("demux_qt: version %d for hdlr atom is higher than the highest supported version (%d)\n",
+ hdlr_atom_version, hdlr_atom_max_version);
+ return;
+ }
+
+ handler_type = _X_BE_32(&current_atom[12]);
+ }
+ break;
+
+ case ILST_ATOM: {
+ uint32_t j = i + 8;
+ while ( j < current_atom_size ) {
+ const uint8_t *const sub_atom = &meta_atom[j];
+ const qt_atom sub_atom_code = _X_BE_32(&sub_atom[4]);
+ const uint32_t sub_atom_size = _X_BE_32(&sub_atom[0]);
+ char *const data_atom = parse_data_atom(&sub_atom[8]);
+
+ switch(sub_atom_code) {
+ case ART_ATOM:
+ info->artist = data_atom;
+ break;
+ case NAM_ATOM:
+ info->name = data_atom;
+ break;
+ case ALB_ATOM:
+ info->album = data_atom;
+ break;
+ case GEN_ATOM:
+ info->genre = data_atom;
+ break;
+ case CMT_ATOM:
+ info->comment = data_atom;
+ break;
+ case WRT_ATOM:
+ info->composer = data_atom;
+ break;
+ case DAY_ATOM:
+ info->year = data_atom;
+ break;
+ default:
+ debug_meta_load("unknown atom %08x in ilst\n", sub_atom_code);
+ free(data_atom);
+ }
+
+ j += sub_atom_size;
+ }
+ }
+ break;
+
+ default:
+ debug_meta_load("unknown atom %08x in meta\n", current_atom_code);
}
+
+ i += current_atom_size;
}
}
@@ -781,10 +847,10 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) {
/* fetch interesting information from the movie header atom */
static void parse_mvhd_atom(qt_info *info, unsigned char *mvhd_atom) {
- info->creation_time = BE_32(&mvhd_atom[0x0C]);
- info->modification_time = BE_32(&mvhd_atom[0x10]);
- info->timescale = BE_32(&mvhd_atom[0x14]);
- info->duration = BE_32(&mvhd_atom[0x18]);
+ info->creation_time = _X_BE_32(&mvhd_atom[0x0C]);
+ info->modification_time = _X_BE_32(&mvhd_atom[0x10]);
+ info->timescale = _X_BE_32(&mvhd_atom[0x14]);
+ info->duration = _X_BE_32(&mvhd_atom[0x18]);
debug_atom_load(" qt: timescale = %d, duration = %d (%d seconds)\n",
info->timescale, info->duration,
@@ -815,25 +881,11 @@ static qt_error parse_trak_atom (qt_trak *trak,
unsigned char *trak_atom) {
int i, j, k;
- unsigned int trak_atom_size = BE_32(&trak_atom[0]);
- qt_atom current_atom;
- unsigned int current_atom_size;
+ const unsigned int trak_atom_size = _X_BE_32(&trak_atom[0]);
unsigned int atom_pos;
unsigned int properties_offset;
- unsigned int current_stsd_atom_size;
qt_error last_error = QT_OK;
- /* for palette traversal */
- int color_depth;
- int color_flag;
- int color_start;
- int color_count;
- int color_end;
- int color_index;
- int color_dec;
- int color_greyscale;
- unsigned char *color_table;
-
/* initialize trak structure */
trak->edit_list_count = 0;
trak->edit_list_table = NULL;
@@ -864,12 +916,13 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* search for media type atoms */
for (i = ATOM_PREAMBLE_SIZE; i < trak_atom_size - 4; i++) {
- current_atom = BE_32(&trak_atom[i]);
+ const qt_atom current_atom = _X_BE_32(&trak_atom[i]);
- if (current_atom == VMHD_ATOM) {
+ switch (current_atom) {
+ case VMHD_ATOM:
trak->type = MEDIA_VIDEO;
break;
- } else if (current_atom == SMHD_ATOM) {
+ case SMHD_ATOM:
trak->type = MEDIA_AUDIO;
break;
}
@@ -881,20 +934,22 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* search for the useful atoms */
for (i = ATOM_PREAMBLE_SIZE; i < trak_atom_size - 4; i++) {
- current_atom_size = BE_32(&trak_atom[i - 4]);
- current_atom = BE_32(&trak_atom[i]);
+ const uint32_t current_atom_size = _X_BE_32(&trak_atom[i - 4]);
+ const qt_atom current_atom = _X_BE_32(&trak_atom[i]);
- if (current_atom == TKHD_ATOM) {
- trak->flags = BE_16(&trak_atom[i + 6]);
- } else if (current_atom == ELST_ATOM) {
+ switch(current_atom) {
+ case TKHD_ATOM:
+ trak->flags = _X_BE_16(&trak_atom[i + 6]);
+ break;
+ case ELST_ATOM:
/* there should only be one edit list table */
if (trak->edit_list_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->edit_list_count = BE_32(&trak_atom[i + 8]);
+ trak->edit_list_count = _X_BE_32(&trak_atom[i + 8]);
debug_atom_load(" qt elst atom (edit list atom): %d entries\n",
trak->edit_list_count);
@@ -909,40 +964,57 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the edit list table */
for (j = 0; j < trak->edit_list_count; j++) {
trak->edit_list_table[j].track_duration =
- BE_32(&trak_atom[i + 12 + j * 12 + 0]);
+ _X_BE_32(&trak_atom[i + 12 + j * 12 + 0]);
trak->edit_list_table[j].media_time =
- BE_32(&trak_atom[i + 12 + j * 12 + 4]);
+ _X_BE_32(&trak_atom[i + 12 + j * 12 + 4]);
debug_atom_load(" %d: track duration = %d, media time = %d\n",
j,
trak->edit_list_table[j].track_duration,
trak->edit_list_table[j].media_time);
}
+ break;
- } else if (current_atom == MDHD_ATOM)
- trak->timescale = BE_32(&trak_atom[i + 0x10]);
- else if (current_atom == STSD_ATOM) {
+ case MDHD_ATOM:
+ debug_atom_load ("demux_qt: mdhd atom\n");
+ {
+ const int version = trak_atom[i+4];
+ if ( version > 1 ) continue; /* unsupported, undocumented */
+ trak->timescale = _X_BE_32(&trak_atom[i + (version == 0 ? 0x10 : 0x18) ]);
+ }
+ break;
+
+ case STSD_ATOM:
debug_atom_load ("demux_qt: stsd atom\n");
#if DEBUG_ATOM_LOAD
xine_hexdump (&trak_atom[i], current_atom_size);
#endif
/* allocate space for each of the properties unions */
- trak->stsd_atoms_count = BE_32(&trak_atom[i + 8]);
- trak->stsd_atoms = xine_xmalloc(trak->stsd_atoms_count * sizeof(properties_t));
+ trak->stsd_atoms_count = _X_BE_32(&trak_atom[i + 8]);
+ trak->stsd_atoms = xine_xcalloc(trak->stsd_atoms_count, sizeof(properties_t));
if (!trak->stsd_atoms) {
last_error = QT_NO_MEMORY;
goto free_trak;
}
- memset(trak->stsd_atoms, 0, trak->stsd_atoms_count * sizeof(properties_t));
atom_pos = i + 0x10;
properties_offset = 0x0C;
for (k = 0; k < trak->stsd_atoms_count; k++) {
- current_stsd_atom_size = BE_32(&trak_atom[atom_pos - 4]);
+ const uint32_t current_stsd_atom_size = _X_BE_32(&trak_atom[atom_pos - 4]);
if (trak->type == MEDIA_VIDEO) {
+ /* for palette traversal */
+ int color_depth;
+ int color_flag;
+ int color_start;
+ int color_count;
+ int color_end;
+ int color_index;
+ int color_dec;
+ int color_greyscale;
+ const unsigned char *color_table;
trak->stsd_atoms[k].video.media_id = k + 1;
trak->stsd_atoms[k].video.properties_offset = properties_offset;
@@ -963,15 +1035,15 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].video.palette_count = 0;
/* fetch video parameters */
- if( BE_16(&trak_atom[atom_pos + 0x1C]) &&
- BE_16(&trak_atom[atom_pos + 0x1E]) ) {
+ if( _X_BE_16(&trak_atom[atom_pos + 0x1C]) &&
+ _X_BE_16(&trak_atom[atom_pos + 0x1E]) ) {
trak->stsd_atoms[k].video.width =
- BE_16(&trak_atom[atom_pos + 0x1C]);
+ _X_BE_16(&trak_atom[atom_pos + 0x1C]);
trak->stsd_atoms[k].video.height =
- BE_16(&trak_atom[atom_pos + 0x1E]);
+ _X_BE_16(&trak_atom[atom_pos + 0x1E]);
}
trak->stsd_atoms[k].video.codec_fourcc =
- ME_32(&trak_atom[atom_pos + 0x00]);
+ _X_ME_32(&trak_atom[atom_pos + 0x00]);
/* figure out the palette situation */
color_depth = trak_atom[atom_pos + 0x4F];
@@ -982,7 +1054,7 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* if the depth is 2, 4, or 8 bpp, file is palettized */
if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) {
- color_flag = BE_16(&trak_atom[atom_pos + 0x50]);
+ color_flag = _X_BE_16(&trak_atom[atom_pos + 0x50]);
if (color_greyscale) {
@@ -1034,15 +1106,15 @@ static qt_error parse_trak_atom (qt_trak *trak,
} else {
/* load the palette from the file */
- color_start = BE_32(&trak_atom[atom_pos + 0x52]);
- color_count = BE_16(&trak_atom[atom_pos + 0x56]);
- color_end = BE_16(&trak_atom[atom_pos + 0x58]);
+ color_start = _X_BE_32(&trak_atom[atom_pos + 0x52]);
+ color_count = _X_BE_16(&trak_atom[atom_pos + 0x56]);
+ color_end = _X_BE_16(&trak_atom[atom_pos + 0x58]);
trak->stsd_atoms[k].video.palette_count =
color_end + 1;
for (j = color_start; j <= color_end; j++) {
- color_index = BE_16(&trak_atom[atom_pos + 0x5A + j * 8]);
+ color_index = _X_BE_16(&trak_atom[atom_pos + 0x5A + j * 8]);
if (color_count & 0x8000)
color_index = j;
if (color_index <
@@ -1071,7 +1143,7 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak_atom[atom_pos + 0x1],
trak_atom[atom_pos + 0x2],
trak_atom[atom_pos + 0x3]);
- debug_atom_load(" %d RGB colors\n",
+ debug_atom_load(" %d RGB colours\n",
trak->stsd_atoms[k].video.palette_count);
for (j = 0; j < trak->stsd_atoms[k].video.palette_count;
j++)
@@ -1095,9 +1167,9 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* fetch audio parameters */
trak->stsd_atoms[k].audio.codec_fourcc =
- ME_32(&trak_atom[atom_pos + 0x0]);
+ _X_ME_32(&trak_atom[atom_pos + 0x0]);
trak->stsd_atoms[k].audio.sample_rate =
- BE_16(&trak_atom[atom_pos + 0x1C]);
+ _X_BE_16(&trak_atom[atom_pos + 0x1C]);
trak->stsd_atoms[k].audio.channels = trak_atom[atom_pos + 0x15];
trak->stsd_atoms[k].audio.bits = trak_atom[atom_pos + 0x17];
@@ -1169,18 +1241,18 @@ static qt_error parse_trak_atom (qt_trak *trak,
(trak->stsd_atoms[k].audio.codec_fourcc != SOWT_FOURCC) &&
(trak->stsd_atoms[k].audio.codec_fourcc != RAW_FOURCC)) {
- if (BE_32(&trak_atom[atom_pos + 0x20]))
+ if (_X_BE_32(&trak_atom[atom_pos + 0x20]))
trak->stsd_atoms[k].audio.samples_per_packet =
- BE_32(&trak_atom[atom_pos + 0x20]);
- if (BE_32(&trak_atom[atom_pos + 0x24]))
+ _X_BE_32(&trak_atom[atom_pos + 0x20]);
+ if (_X_BE_32(&trak_atom[atom_pos + 0x24]))
trak->stsd_atoms[k].audio.bytes_per_packet =
- BE_32(&trak_atom[atom_pos + 0x24]);
- if (BE_32(&trak_atom[atom_pos + 0x28]))
+ _X_BE_32(&trak_atom[atom_pos + 0x24]);
+ if (_X_BE_32(&trak_atom[atom_pos + 0x28]))
trak->stsd_atoms[k].audio.bytes_per_frame =
- BE_32(&trak_atom[atom_pos + 0x28]);
- if (BE_32(&trak_atom[atom_pos + 0x2C]))
+ _X_BE_32(&trak_atom[atom_pos + 0x28]);
+ if (_X_BE_32(&trak_atom[atom_pos + 0x2C]))
trak->stsd_atoms[k].audio.bytes_per_sample =
- BE_32(&trak_atom[atom_pos + 0x2C]);
+ _X_BE_32(&trak_atom[atom_pos + 0x2C]);
trak->stsd_atoms[k].audio.samples_per_frame =
(trak->stsd_atoms[k].audio.bytes_per_frame /
trak->stsd_atoms[k].audio.bytes_per_packet) *
@@ -1188,7 +1260,7 @@ static qt_error parse_trak_atom (qt_trak *trak,
}
/* see if the trak deserves a promotion to VBR */
- if (BE_16(&trak_atom[atom_pos + 0x18]) == 0xFFFE)
+ if (_X_BE_16(&trak_atom[atom_pos + 0x18]) == 0xFFFE)
trak->stsd_atoms[k].audio.vbr = 1;
else
trak->stsd_atoms[k].audio.vbr = 0;
@@ -1218,10 +1290,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* check for a MS-style WAVE format header */
if ((current_atom_size >= 0x4C) &&
- (BE_32(&trak_atom[atom_pos + 0x34]) == WAVE_ATOM) &&
- (BE_32(&trak_atom[atom_pos + 0x3C]) == FRMA_ATOM) &&
- (ME_32(&trak_atom[atom_pos + 0x48]) == trak->stsd_atoms[k].audio.codec_fourcc)) {
- int wave_size = BE_32(&trak_atom[atom_pos + 0x44]) - 8;
+ (_X_BE_32(&trak_atom[atom_pos + 0x34]) == WAVE_ATOM) &&
+ (_X_BE_32(&trak_atom[atom_pos + 0x3C]) == FRMA_ATOM) &&
+ (_X_ME_32(&trak_atom[atom_pos + 0x48]) == trak->stsd_atoms[k].audio.codec_fourcc)) {
+ const int wave_size = _X_BE_32(&trak_atom[atom_pos + 0x44]) - 8;
if ((wave_size >= sizeof(xine_waveformatex)) &&
(current_atom_size >= (0x4C + wave_size))) {
@@ -1271,15 +1343,15 @@ static qt_error parse_trak_atom (qt_trak *trak,
atom_pos += current_stsd_atom_size;
properties_offset += current_stsd_atom_size;
}
-
- } else if (current_atom == ESDS_ATOM) {
-
- uint32_t len;
+ break;
+
+ case ESDS_ATOM:
debug_atom_load(" qt/mpeg-4 esds atom\n");
if ((trak->type == MEDIA_VIDEO) ||
(trak->type == MEDIA_AUDIO)) {
+ uint32_t len;
j = i + 8;
if( trak_atom[j++] == 0x03 ) {
@@ -1302,25 +1374,25 @@ static qt_error parse_trak_atom (qt_trak *trak,
}
}
}
+ break;
- } else if (current_atom == AVCC_ATOM) {
-
+ case AVCC_ATOM:
debug_atom_load(" avcC atom\n");
trak->decoder_config_len = current_atom_size - 8;
trak->decoder_config = realloc(trak->decoder_config, trak->decoder_config_len);
memcpy(trak->decoder_config, &trak_atom[i + 4], trak->decoder_config_len);
+ break;
- } else if (current_atom == STSZ_ATOM) {
-
+ case STSZ_ATOM:
/* there should only be one of these atoms */
if (trak->sample_size_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->sample_size = BE_32(&trak_atom[i + 8]);
- trak->sample_size_count = BE_32(&trak_atom[i + 12]);
+ trak->sample_size = _X_BE_32(&trak_atom[i + 8]);
+ trak->sample_size_count = _X_BE_32(&trak_atom[i + 12]);
debug_atom_load(" qt stsz atom (sample size atom): sample size = %d, %d entries\n",
trak->sample_size, trak->sample_size_count);
@@ -1336,7 +1408,7 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the sample size table */
for (j = 0; j < trak->sample_size_count; j++) {
trak->sample_size_table[j] =
- BE_32(&trak_atom[i + 16 + j * 4]);
+ _X_BE_32(&trak_atom[i + 16 + j * 4]);
debug_atom_load(" sample size %d: %d\n",
j, trak->sample_size_table[j]);
}
@@ -1344,16 +1416,16 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* set the pointer to non-NULL to indicate that the atom type has
* already been seen for this trak atom */
trak->sample_size_table = (void *)-1;
+ break;
- } else if (current_atom == STSS_ATOM) {
-
+ case STSS_ATOM:
/* there should only be one of these atoms */
if (trak->sync_sample_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->sync_sample_count = BE_32(&trak_atom[i + 8]);
+ trak->sync_sample_count = _X_BE_32(&trak_atom[i + 8]);
debug_atom_load(" qt stss atom (sample sync atom): %d sync samples\n",
trak->sync_sample_count);
@@ -1368,27 +1440,26 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the sync sample table */
for (j = 0; j < trak->sync_sample_count; j++) {
trak->sync_sample_table[j] =
- BE_32(&trak_atom[i + 12 + j * 4]);
+ _X_BE_32(&trak_atom[i + 12 + j * 4]);
debug_atom_load(" sync sample %d: sample %d (%d) is a keyframe\n",
j, trak->sync_sample_table[j],
trak->sync_sample_table[j] - 1);
}
+ break;
- } else if (current_atom == STCO_ATOM) {
-
+ case STCO_ATOM:
/* there should only be one of either stco or co64 */
if (trak->chunk_offset_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->chunk_offset_count = BE_32(&trak_atom[i + 8]);
+ trak->chunk_offset_count = _X_BE_32(&trak_atom[i + 8]);
debug_atom_load(" qt stco atom (32-bit chunk offset atom): %d chunk offsets\n",
trak->chunk_offset_count);
- trak->chunk_offset_table = (int64_t *)malloc(
- trak->chunk_offset_count * sizeof(int64_t));
+ trak->chunk_offset_table = calloc(trak->chunk_offset_count, sizeof(int64_t));
if (!trak->chunk_offset_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1397,26 +1468,25 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the chunk offset table */
for (j = 0; j < trak->chunk_offset_count; j++) {
trak->chunk_offset_table[j] =
- BE_32(&trak_atom[i + 12 + j * 4]);
+ _X_BE_32(&trak_atom[i + 12 + j * 4]);
debug_atom_load(" chunk %d @ 0x%"PRIX64"\n",
j, trak->chunk_offset_table[j]);
}
+ break;
- } else if (current_atom == CO64_ATOM) {
-
+ case CO64_ATOM:
/* there should only be one of either stco or co64 */
if (trak->chunk_offset_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->chunk_offset_count = BE_32(&trak_atom[i + 8]);
+ trak->chunk_offset_count = _X_BE_32(&trak_atom[i + 8]);
debug_atom_load(" qt co64 atom (64-bit chunk offset atom): %d chunk offsets\n",
trak->chunk_offset_count);
- trak->chunk_offset_table = (int64_t *)malloc(
- trak->chunk_offset_count * sizeof(int64_t));
+ trak->chunk_offset_table = calloc(trak->chunk_offset_count, sizeof(int64_t));
if (!trak->chunk_offset_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1425,29 +1495,28 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the 64-bit chunk offset table */
for (j = 0; j < trak->chunk_offset_count; j++) {
trak->chunk_offset_table[j] =
- BE_32(&trak_atom[i + 12 + j * 8 + 0]);
+ _X_BE_32(&trak_atom[i + 12 + j * 8 + 0]);
trak->chunk_offset_table[j] <<= 32;
trak->chunk_offset_table[j] |=
- BE_32(&trak_atom[i + 12 + j * 8 + 4]);
+ _X_BE_32(&trak_atom[i + 12 + j * 8 + 4]);
debug_atom_load(" chunk %d @ 0x%"PRIX64"\n",
j, trak->chunk_offset_table[j]);
}
+ break;
- } else if (current_atom == STSC_ATOM) {
-
+ case STSC_ATOM:
/* there should only be one of these atoms */
if (trak->sample_to_chunk_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->sample_to_chunk_count = BE_32(&trak_atom[i + 8]);
+ trak->sample_to_chunk_count = _X_BE_32(&trak_atom[i + 8]);
debug_atom_load(" qt stsc atom (sample-to-chunk atom): %d entries\n",
trak->sample_to_chunk_count);
- trak->sample_to_chunk_table = (sample_to_chunk_table_t *)malloc(
- trak->sample_to_chunk_count * sizeof(sample_to_chunk_table_t));
+ trak->sample_to_chunk_table = calloc(trak->sample_to_chunk_count, sizeof(sample_to_chunk_table_t));
if (!trak->sample_to_chunk_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1456,33 +1525,32 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the sample to chunk table */
for (j = 0; j < trak->sample_to_chunk_count; j++) {
trak->sample_to_chunk_table[j].first_chunk =
- BE_32(&trak_atom[i + 12 + j * 12 + 0]);
+ _X_BE_32(&trak_atom[i + 12 + j * 12 + 0]);
trak->sample_to_chunk_table[j].samples_per_chunk =
- BE_32(&trak_atom[i + 12 + j * 12 + 4]);
+ _X_BE_32(&trak_atom[i + 12 + j * 12 + 4]);
trak->sample_to_chunk_table[j].media_id =
- BE_32(&trak_atom[i + 12 + j * 12 + 8]);
+ _X_BE_32(&trak_atom[i + 12 + j * 12 + 8]);
debug_atom_load(" %d: %d samples/chunk starting at chunk %d (%d) for media id %d\n",
j, trak->sample_to_chunk_table[j].samples_per_chunk,
trak->sample_to_chunk_table[j].first_chunk,
trak->sample_to_chunk_table[j].first_chunk - 1,
trak->sample_to_chunk_table[j].media_id);
}
+ break;
- } else if (current_atom == STTS_ATOM) {
-
+ case STTS_ATOM:
/* there should only be one of these atoms */
if (trak->time_to_sample_table) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
- trak->time_to_sample_count = BE_32(&trak_atom[i + 8]);
+ trak->time_to_sample_count = _X_BE_32(&trak_atom[i + 8]);
debug_atom_load(" qt stts atom (time-to-sample atom): %d entries\n",
trak->time_to_sample_count);
- trak->time_to_sample_table = (time_to_sample_table_t *)malloc(
- (trak->time_to_sample_count+1) * sizeof(time_to_sample_table_t));
+ trak->time_to_sample_table = calloc(trak->time_to_sample_count+1, sizeof(time_to_sample_table_t));
if (!trak->time_to_sample_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1491,9 +1559,9 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* load the time to sample table */
for (j = 0; j < trak->time_to_sample_count; j++) {
trak->time_to_sample_table[j].count =
- BE_32(&trak_atom[i + 12 + j * 8 + 0]);
+ _X_BE_32(&trak_atom[i + 12 + j * 8 + 0]);
trak->time_to_sample_table[j].duration =
- BE_32(&trak_atom[i + 12 + j * 8 + 4]);
+ _X_BE_32(&trak_atom[i + 12 + j * 8 + 4]);
debug_atom_load(" %d: count = %d, duration = %d\n",
j, trak->time_to_sample_table[j].count,
trak->time_to_sample_table[j].duration);
@@ -1529,9 +1597,7 @@ static qt_error parse_reference_atom (reference_t *ref,
char *base_mrl) {
int i, j;
- unsigned int ref_atom_size = BE_32(&ref_atom[0]);
- qt_atom current_atom;
- unsigned int current_atom_size;
+ const unsigned int ref_atom_size = _X_BE_32(&ref_atom[0]);
/* initialize reference atom */
ref->url = NULL;
@@ -1540,59 +1606,54 @@ static qt_error parse_reference_atom (reference_t *ref,
/* traverse through the atom looking for the key atoms */
for (i = ATOM_PREAMBLE_SIZE; i < ref_atom_size - 4; i++) {
+ const uint32_t current_atom_size = _X_BE_32(&ref_atom[i - 4]);
+ const qt_atom current_atom = _X_BE_32(&ref_atom[i]);
- current_atom_size = BE_32(&ref_atom[i - 4]);
- current_atom = BE_32(&ref_atom[i]);
-
- if (current_atom == RDRF_ATOM) {
+ switch (current_atom) {
+ case RDRF_ATOM: {
+ size_t string_size = _X_BE_32(&ref_atom[i + 12]);
+ size_t url_offset = 0;
/* if the URL starts with "http://", copy it */
- if (strncmp(&ref_atom[i + 16], "http://", 7) == 0
- || strncmp(&ref_atom[i + 16], "rtsp://", 7) == 0) {
+ if ( memcmp(&ref_atom[i + 16], "http://", 7) &&
+ memcmp(&ref_atom[i + 16], "rtsp://", 7) &&
+ base_mrl )
+ url_offset = strlen(base_mrl);
- /* URL is spec'd to terminate with a NULL; don't trust it */
- ref->url = xine_xmalloc(BE_32(&ref_atom[i + 12]) + 1);
- strncpy(ref->url, &ref_atom[i + 16], BE_32(&ref_atom[i + 12]));
- ref->url[BE_32(&ref_atom[i + 12]) - 1] = '\0';
+ /* otherwise, append relative URL to base MRL */
+ string_size += url_offset;
- } else {
+ ref->url = xine_xmalloc(string_size + 1);
- int string_size;
+ if ( url_offset )
+ strcpy(ref->url, base_mrl);
- if (base_mrl)
- string_size = strlen(base_mrl) + BE_32(&ref_atom[i + 12]) + 1;
- else
- string_size = BE_32(&ref_atom[i + 12]) + 1;
+ memcpy(ref->url + url_offset, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12]));
- /* otherwise, append relative URL to base MRL */
- ref->url = xine_xmalloc(string_size);
- if (base_mrl)
- strcpy(ref->url, base_mrl);
- strncat(ref->url, &ref_atom[i + 16], BE_32(&ref_atom[i + 12]));
- ref->url[string_size - 1] = '\0';
- }
+ ref->url[string_size] = '\0';
+ }
debug_atom_load(" qt rdrf URL reference:\n %s\n", ref->url);
+ break;
- } else if (current_atom == RMDR_ATOM) {
-
+ case RMDR_ATOM:
/* load the data rate */
- ref->data_rate = BE_32(&ref_atom[i + 8]);
+ ref->data_rate = _X_BE_32(&ref_atom[i + 8]);
ref->data_rate *= 10;
debug_atom_load(" qt rmdr data rate = %"PRId64"\n", ref->data_rate);
+ break;
- } else if (current_atom == RMVC_ATOM) {
-
+ case RMVC_ATOM:
debug_atom_load(" qt rmvc atom\n");
/* search the rmvc atom for 'qtim'; 2 bytes will follow the qtim
* chars so only search to 6 bytes to the end */
for (j = 4; j < current_atom_size - 6; j++) {
- if (BE_32(&ref_atom[i + j]) == QTIM_ATOM) {
+ if (_X_BE_32(&ref_atom[i + j]) == QTIM_ATOM) {
- ref->qtim_version = BE_16(&ref_atom[i + j + 4]);
+ ref->qtim_version = _X_BE_16(&ref_atom[i + j + 4]);
debug_atom_load(" qtim version = %04X\n", ref->qtim_version);
}
}
@@ -1606,7 +1667,7 @@ static qt_error parse_reference_atom (reference_t *ref,
* building a frame table. */
#define MAX_DURATION 0x7FFFFFFFFFFFFFFFLL
static void get_next_edit_list_entry(qt_trak *trak,
- int *edit_list_index,
+ unsigned int *edit_list_index,
unsigned int *edit_list_media_time,
int64_t *edit_list_duration,
unsigned int global_timescale) {
@@ -1682,8 +1743,7 @@ static qt_error build_frame_table(qt_trak *trak,
/* in this case, the total number of frames is equal to the number of
* entries in the sample size table */
trak->frame_count = trak->sample_size_count;
- trak->frames = (qt_frame *)malloc(
- trak->frame_count * sizeof(qt_frame));
+ trak->frames = calloc(trak->frame_count, sizeof(qt_frame));
if (!trak->frames)
return QT_NO_MEMORY;
trak->current_frame = 0;
@@ -1695,10 +1755,9 @@ static qt_error build_frame_table(qt_trak *trak,
pts_index_countdown =
trak->time_to_sample_table[pts_index].count;
- media_id_counts = xine_xmalloc(trak->stsd_atoms_count * sizeof(int));
+ media_id_counts = xine_xcalloc(trak->stsd_atoms_count, sizeof(int));
if (!media_id_counts)
return QT_NO_MEMORY;
- memset(media_id_counts, 0, trak->stsd_atoms_count * sizeof(int));
/* iterate through each start chunk in the stsc table */
for (i = 0; i < trak->sample_to_chunk_count; i++) {
@@ -1833,8 +1892,7 @@ static qt_error build_frame_table(qt_trak *trak,
/* in this case, the total number of frames is equal to the number of
* chunks */
trak->frame_count = trak->chunk_offset_count;
- trak->frames = (qt_frame *)malloc(
- trak->frame_count * sizeof(qt_frame));
+ trak->frames = calloc(trak->frame_count, sizeof(qt_frame));
if (!trak->frames)
return QT_NO_MEMORY;
@@ -1910,31 +1968,32 @@ static qt_error build_frame_table(qt_trak *trak,
static void parse_moov_atom(qt_info *info, unsigned char *moov_atom,
int64_t bandwidth) {
int i, j;
- unsigned int moov_atom_size = BE_32(&moov_atom[0]);
- qt_atom current_atom;
+ unsigned int moov_atom_size = _X_BE_32(&moov_atom[0]);
int string_size, error;
unsigned int max_video_frames = 0;
unsigned int max_audio_frames = 0;
/* make sure this is actually a moov atom (will also accept 'free' as
* a special case) */
- if ((BE_32(&moov_atom[4]) != MOOV_ATOM) &&
- (BE_32(&moov_atom[4]) != FREE_ATOM)) {
+ if ((_X_BE_32(&moov_atom[4]) != MOOV_ATOM) &&
+ (_X_BE_32(&moov_atom[4]) != FREE_ATOM)) {
info->last_error = QT_NO_MOOV_ATOM;
return;
}
/* prowl through the moov atom looking for very specific targets */
- for (i = ATOM_PREAMBLE_SIZE + 4; i < moov_atom_size - 4; i += BE_32(&moov_atom[i - 4])) {
- current_atom = BE_32(&moov_atom[i]);
+ for (i = ATOM_PREAMBLE_SIZE + 4; i < moov_atom_size - 4; i += _X_BE_32(&moov_atom[i - 4])) {
+ const qt_atom current_atom = _X_BE_32(&moov_atom[i]);
- if (current_atom == MVHD_ATOM) {
+ switch (current_atom) {
+ case MVHD_ATOM:
parse_mvhd_atom(info, &moov_atom[i - 4]);
if (info->last_error != QT_OK)
return;
- } else if (current_atom == TRAK_ATOM) {
+ break;
+ case TRAK_ATOM:
/* create a new trak structure */
info->trak_count++;
info->traks = (qt_trak *)realloc(info->traks,
@@ -1946,43 +2005,50 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom,
info->trak_count--;
return;
}
+ break;
+
+ case UDTA_ATOM:
+ parse_meta_atom(info, &moov_atom[i + 4]);
+ if (info->last_error != QT_OK)
+ return;
+ break;
- } else if (current_atom == META_ATOM) {
-
+ case META_ATOM:
parse_meta_atom(info, &moov_atom[i - 4]);
if (info->last_error != QT_OK)
return;
+ break;
- } else if (current_atom == NAM_ATOM) {
-
- string_size = BE_16(&moov_atom[i + 4]) + 1;
- info->name = realloc (info->name, string_size);
- strncpy(info->name, &moov_atom[i + 8], string_size - 1);
- info->name[string_size - 1] = 0;
-
- } else if (current_atom == CPY_ATOM) {
-
- string_size = BE_16(&moov_atom[i + 4]) + 1;
- info->copyright = realloc (info->copyright, string_size);
- strncpy(info->copyright, &moov_atom[i + 8], string_size - 1);
- info->copyright[string_size - 1] = 0;
-
- } else if (current_atom == DES_ATOM) {
-
- string_size = BE_16(&moov_atom[i + 4]) + 1;
- info->description = realloc (info->description, string_size);
- strncpy(info->description, &moov_atom[i + 8], string_size - 1);
- info->description[string_size - 1] = 0;
+ case NAM_ATOM:
+ string_size = _X_BE_16(&moov_atom[i + 4]);
+ info->name = realloc (info->name, string_size + 1);
+ memcpy(info->name, &moov_atom[i + 8], string_size);
+ info->name[string_size] = 0;
+ break;
- } else if (current_atom == CMT_ATOM) {
+ case CPY_ATOM:
+ string_size = _X_BE_16(&moov_atom[i + 4]);
+ info->copyright = realloc (info->copyright, string_size + 1);
+ memcpy(info->copyright, &moov_atom[i + 8], string_size);
+ info->copyright[string_size] = 0;
+ break;
- string_size = BE_16(&moov_atom[i + 4]) + 1;
- info->comment = realloc (info->comment, string_size);
- strncpy(info->comment, &moov_atom[i + 8], string_size - 1);
- info->comment[string_size - 1] = 0;
+ case DES_ATOM:
+ string_size = _X_BE_16(&moov_atom[i + 4]);
+ info->description = realloc (info->description, string_size + 1);
+ memcpy(info->description, &moov_atom[i + 8], string_size);
+ info->description[string_size] = 0;
+ break;
- } else if (current_atom == RMDA_ATOM) {
+ case CMT_ATOM:
+ string_size = _X_BE_16(&moov_atom[i + 4]);
+ info->comment = realloc (info->comment, string_size + 1);
+ memcpy(info->comment, &moov_atom[i + 8], string_size);
+ info->comment[string_size] = 0;
+ break;
+ case RMDA_ATOM:
+ case RMRA_ATOM:
/* create a new reference structure */
info->reference_count++;
info->references = (reference_t *)realloc(info->references,
@@ -1990,8 +2056,9 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom,
parse_reference_atom(&info->references[info->reference_count - 1],
&moov_atom[i - 4], info->base_mrl);
+ break;
- } else {
+ default:
debug_atom_load(" qt: unknown atom into the moov atom (0x%08X)\n", current_atom);
}
}
@@ -2067,7 +2134,6 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input,
unsigned char *moov_atom = NULL;
off_t moov_atom_offset = -1;
int64_t moov_atom_size = -1;
- unsigned char preview[MAX_PREVIEW_SIZE];
/* zlib stuff */
z_stream z_state;
@@ -2090,26 +2156,26 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input,
if ((input->get_capabilities(input) & INPUT_CAP_SEEKABLE))
find_moov_atom(input, &moov_atom_offset, &moov_atom_size);
else {
- memset (&preview, 0, MAX_PREVIEW_SIZE);
+ unsigned char preview[MAX_PREVIEW_SIZE] = { 0, };
input->get_optional_data(input, preview, INPUT_OPTIONAL_DATA_PREVIEW);
- if (BE_32(&preview[4]) != MOOV_ATOM) {
+ if (_X_BE_32(&preview[4]) != MOOV_ATOM) {
/* special case if there is an ftyp atom first */
- if (BE_32(&preview[4]) == FTYP_ATOM) {
- moov_atom_size = BE_32(&preview[0]);
+ if (_X_BE_32(&preview[4]) == FTYP_ATOM) {
+ moov_atom_size = _X_BE_32(&preview[0]);
if ((moov_atom_size + ATOM_PREAMBLE_SIZE >= MAX_PREVIEW_SIZE) ||
- (BE_32(&preview[moov_atom_size + 4]) != MOOV_ATOM)) {
+ (_X_BE_32(&preview[moov_atom_size + 4]) != MOOV_ATOM)) {
info->last_error = QT_NO_MOOV_ATOM;
return info->last_error;
}
moov_atom_offset = moov_atom_size;
- moov_atom_size = BE_32(&preview[moov_atom_offset]);
+ moov_atom_size = _X_BE_32(&preview[moov_atom_offset]);
} else {
info->last_error = QT_NO_MOOV_ATOM;
return info->last_error;
}
} else {
moov_atom_offset = 0;
- moov_atom_size = BE_32(&preview[0]);
+ moov_atom_size = _X_BE_32(&preview[0]);
}
}
@@ -2140,14 +2206,14 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input,
}
/* check if moov is compressed */
- if (BE_32(&moov_atom[12]) == CMOV_ATOM) {
+ if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM) {
info->compressed_header = 1;
z_state.next_in = &moov_atom[0x28];
z_state.avail_in = moov_atom_size - 0x28;
- z_state.avail_out = BE_32(&moov_atom[0x24]);
- unzip_buffer = (unsigned char *)malloc(BE_32(&moov_atom[0x24]));
+ z_state.avail_out = _X_BE_32(&moov_atom[0x24]);
+ unzip_buffer = (unsigned char *)malloc(_X_BE_32(&moov_atom[0x24]));
if (!unzip_buffer) {
free(moov_atom);
info->last_error = QT_NO_MEMORY;
@@ -2186,7 +2252,7 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input,
/* replace the compressed moov atom with the decompressed atom */
free (moov_atom);
moov_atom = unzip_buffer;
- moov_atom_size = BE_32(&moov_atom[0]);
+ moov_atom_size = _X_BE_32(&moov_atom[0]);
}
if (!moov_atom) {
@@ -2992,24 +3058,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
break;
- case METHOD_BY_EXTENSION: {
- const char *const mrl = input->get_mrl (input);
- const char *const ending = strrchr(mrl, '.');
-
- if (!ending) {
- free (this);
- return NULL;
- }
-
- if (strncasecmp (ending, ".mov", 4) &&
- strncasecmp (ending, ".qt", 3) &&
- strncasecmp (ending, ".mp4", 4)) {
- free (this);
- return NULL;
- }
- }
-
- /* we want to fall through here */
+ case METHOD_BY_MRL:
case METHOD_EXPLICIT: {
if (!is_qt_file(this->input)) {
@@ -3038,32 +3087,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return &this->demux_plugin;
}
-static const char *get_description (demux_class_t *this_gen) {
- return "Apple Quicktime (MOV) and MPEG-4 demux plugin";
-}
-
-static const char *get_identifier (demux_class_t *this_gen) {
- return "MOV/MPEG-4";
-}
-
-static const char *get_extensions (demux_class_t *this_gen) {
- return "mov qt mp4 m4a m4b";
-}
-
-static const char *get_mimetypes (demux_class_t *this_gen) {
- return "video/quicktime: mov,qt: Quicktime animation;"
- "video/x-quicktime: mov,qt: Quicktime animation;"
- "audio/x-m4a: m4a,m4b: MPEG-4 audio;"
- "application/x-quicktimeplayer: qtl: Quicktime list;";
-}
-
-static void class_dispose (demux_class_t *this_gen) {
-
- demux_qt_class_t *this = (demux_qt_class_t *) this_gen;
-
- free (this);
-}
-
static void *init_plugin (xine_t *xine, void *data) {
demux_qt_class_t *this;
@@ -3073,11 +3096,15 @@ static void *init_plugin (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_("Apple Quicktime (MOV) and MPEG-4 demux plugin");
+ this->demux_class.identifier = "MOV/MPEG-4";
+ this->demux_class.mimetypes =
+ "video/quicktime: mov,qt: Quicktime animation;"
+ "video/x-quicktime: mov,qt: Quicktime animation;"
+ "audio/x-m4a: m4a,m4b: MPEG-4 audio;"
+ "application/x-quicktimeplayer: qtl: Quicktime list;";
+ this->demux_class.extensions = "mov qt mp4 m4a m4b";
+ this->demux_class.dispose = default_demux_class_dispose;
return this;
}
@@ -3091,6 +3118,6 @@ static const demuxer_info_t demux_info_qt = {
const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 26, "quicktime", XINE_VERSION_CODE, &demux_info_qt, init_plugin },
+ { PLUGIN_DEMUX, 27, "quicktime", XINE_VERSION_CODE, &demux_info_qt, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};