*
* You should have received a copy of the GNU Lesser 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
#include "avformat.h"
/* For codec_get_bmp_id and codec_get_wav_id. */
#include "avi.h"
+#include "intfloat_readwrite.h"
/* EBML version supported */
#define EBML_VERSION 1
#define MATROSKA_CODEC_ID_VIDEO_MPEG4_SP "V_MPEG4/ISO/SP"
#define MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP "V_MPEG4/ISO/ASP"
#define MATROSKA_CODEC_ID_VIDEO_MPEG4_AP "V_MPEG4/ISO/AP"
+#define MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC "V_MPEG4/ISO/AVC"
#define MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3 "V_MPEG4/MS/V3"
#define MATROSKA_CODEC_ID_VIDEO_MPEG1 "V_MPEG1"
#define MATROSKA_CODEC_ID_VIDEO_MPEG2 "V_MPEG2"
if (!url_feof(pb)) {
offset_t pos = url_ftell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
- "Read error at pos. %llu (0x%llx)\n",
+ "Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
pos, pos);
}
return AVERROR_IO; /* EOS or actual I/O error */
if (read > max_size) {
offset_t pos = url_ftell(pb) - 1;
av_log(matroska->ctx, AV_LOG_ERROR,
- "Invalid EBML number size tag 0x%02x at pos %llu (0x%llx)\n",
+ "Invalid EBML number size tag 0x%02x at pos %"PRIu64" (0x%"PRIx64")\n",
(uint8_t) total, pos, pos);
return AVERROR_INVALIDDATA;
}
if (size < 1 || size > 8) {
offset_t pos = url_ftell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
- "Invalid uint element size %d at position %lld (0x%llx)\n",
+ "Invalid uint element size %d at position %"PRId64" (0x%"PRIx64")\n",
size, pos, pos);
return AVERROR_INVALIDDATA;
}
if (size < 1 || size > 8) {
offset_t pos = url_ftell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
- "Invalid sint element size %d at position %lld (0x%llx)\n",
+ "Invalid sint element size %d at position %"PRId64" (0x%"PRIx64")\n",
size, pos, pos);
return AVERROR_INVALIDDATA;
}
static int
ebml_read_float (MatroskaDemuxContext *matroska,
- uint32_t *id,
- double *num)
+ uint32_t *id,
+ double *num)
{
ByteIOContext *pb = &matroska->ctx->pb;
int size, res;
return res;
size = rlength;
- if (size != 4 && size != 8 && size != 10) {
+ if (size == 4) {
+ *num= av_int2flt(get_be32(pb));
+ } else if(size==8){
+ *num= av_int2dbl(get_be64(pb));
+ } else if(size==10){
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "FIXME! 10-byte floats unimplemented\n");
+ return AVERROR_UNKNOWN;
+ } else{
offset_t pos = url_ftell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
- "Invalid float element size %d at position %llu (0x%llx)\n",
+ "Invalid float element size %d at position %"PRIu64" (0x%"PRIx64")\n",
size, pos, pos);
return AVERROR_INVALIDDATA;
}
- if (size == 10) {
- av_log(matroska->ctx, AV_LOG_ERROR,
- "FIXME! 10-byte floats unimplemented\n");
- return AVERROR_UNKNOWN;
- }
-
- if (size == 4) {
- float f;
-
- while (size-- > 0)
-#ifdef WORDS_BIGENDIAN
- ((uint8_t *) &f)[3 - size] = get_byte(pb);
-#else
- ((uint8_t *) &f)[size] = get_byte(pb);
-#endif
-
- *num = f;
- } else {
- double d;
-
- while (size-- > 0)
-#ifdef WORDS_BIGENDIAN
- ((uint8_t *) &d)[7 - size] = get_byte(pb);
-#else
- ((uint8_t *) &d)[size] = get_byte(pb);
-#endif
-
- *num = d;
- }
return 0;
}
/* ebml strings are usually not 0-terminated, so we allocate one
* byte more, read the string and NULL-terminate it ourselves. */
- if (!(*str = av_malloc(size + 1))) {
+ if (size < 0 || !(*str = av_malloc(size + 1))) {
av_log(matroska->ctx, AV_LOG_ERROR, "Memory allocation failed\n");
return AVERROR_NOMEM;
}
if (get_buffer(pb, (uint8_t *) *str, size) != size) {
offset_t pos = url_ftell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
- "Read error at pos. %llu (0x%llx)\n", pos, pos);
+ "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", pos, pos);
return AVERROR_IO;
}
(*str)[size] = '\0';
if (get_buffer(pb, *binary, *size) != *size) {
offset_t pos = url_ftell(pb);
av_log(matroska->ctx, AV_LOG_ERROR,
- "Read error at pos. %llu (0x%llx)\n", pos, pos);
+ "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", pos, pos);
return AVERROR_IO;
}
n++;
}
- if (!total)
- return AVERROR_INVALIDDATA;
-
if (read == num_ffs)
*num = (uint64_t)-1;
else
return res;
if (num > EBML_VERSION) {
av_log(matroska->ctx, AV_LOG_ERROR,
- "EBML version %llu (> %d) is not supported\n",
+ "EBML version %"PRIu64" (> %d) is not supported\n",
num, EBML_VERSION);
return AVERROR_INVALIDDATA;
}
return res;
if (num > sizeof(uint64_t)) {
av_log(matroska->ctx, AV_LOG_ERROR,
- "Integers of size %llu (> %d) not supported\n",
+ "Integers of size %"PRIu64" (> %zd) not supported\n",
num, sizeof(uint64_t));
return AVERROR_INVALIDDATA;
}
return res;
if (num > sizeof(uint32_t)) {
av_log(matroska->ctx, AV_LOG_ERROR,
- "IDs of size %llu (> %u) not supported\n",
- num, sizeof(uint32_t));
+ "IDs of size %"PRIu64" (> %zu) not supported\n",
+ num, sizeof(uint32_t));
return AVERROR_INVALIDDATA;
}
break;
break;
}
- /* position in the file + track to which it
+ /* position in the file + track to which it
* belongs */
case MATROSKA_ID_CUETRACKPOSITION:
if ((res = ebml_read_master(matroska, &id)) < 0)
if (!seek_id || seek_pos == (uint64_t) -1) {
av_log(matroska->ctx, AV_LOG_INFO,
- "Incomplete seekhead entry (0x%x/%llu)\n",
+ "Incomplete seekhead entry (0x%x/%"PRIu64")\n",
seek_id, seek_pos);
break;
}
"cannot parse further.\n", EBML_MAX_DEPTH);
return AVERROR_UNKNOWN;
}
-
+
level.start = 0;
level.length = (uint64_t)-1;
matroska->levels[matroska->num_levels] = level;
if (id != seek_id) {
av_log(matroska->ctx, AV_LOG_INFO,
"We looked for ID=0x%x but got "
- "ID=0x%x (pos=%llu)",
+ "ID=0x%x (pos=%"PRIu64")",
seek_id, id, seek_pos +
matroska->segment_start);
goto finish;
enum CodecID codec_id;
MatroskaTrack *track;
AVStream *st;
+ void *extradata = NULL;
+ int extradata_size = 0;
for (i = 0; i < matroska->num_tracks; i++) {
track = matroska->tracks[i];
!strcmp(track->codec_id,
MATROSKA_CODEC_ID_VIDEO_MPEG4_AP))
codec_id = CODEC_ID_MPEG4;
+ else if (!strcmp(track->codec_id,
+ MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC))
+ codec_id = CODEC_ID_H264;
/* else if (!strcmp(track->codec_id, */
/* MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) */
/* codec_id = CODEC_ID_???; */
/* This is the MS compatibility mode which stores a
* WAVEFORMATEX in the CodecPrivate. */
- else if (!strcmp(track->codec_id,
+ else if (!strcmp(track->codec_id,
MATROSKA_CODEC_ID_AUDIO_ACM) &&
(track->codec_priv_size >= 18) &&
(track->codec_priv != NULL)) {
/* MATROSKA_CODEC_ID_AUDIO_DTS)) */
/* codec_id = CODEC_ID_DTS; */
else if (!strcmp(track->codec_id,
- MATROSKA_CODEC_ID_AUDIO_VORBIS))
+ MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
+ extradata_size = track->codec_priv_size;
+ if(extradata_size) {
+ extradata = av_malloc(extradata_size);
+ if(extradata == NULL)
+ return AVERROR_NOMEM;
+ memcpy(extradata, track->codec_priv, extradata_size);
+ }
codec_id = CODEC_ID_VORBIS;
- else if (!strcmp(track->codec_id,
- MATROSKA_CODEC_ID_AUDIO_MPEG2) ||
- !strcmp(track->codec_id,
- MATROSKA_CODEC_ID_AUDIO_MPEG4))
+ } else if (!strcmp(track->codec_id,
+ MATROSKA_CODEC_ID_AUDIO_MPEG2) ||
+ !strcmp(track->codec_id,
+ MATROSKA_CODEC_ID_AUDIO_MPEG4))
codec_id = CODEC_ID_AAC;
else
codec_id = CODEC_ID_NONE;
return AVERROR_NOMEM;
av_set_pts_info(st, 24, 1, 1000); /* 24 bit pts in ms */
- st->codec.codec_id = codec_id;
+ st->codec->codec_id = codec_id;
+
+ if(extradata){
+ st->codec->extradata = extradata;
+ st->codec->extradata_size = extradata_size;
+ } else if(track->codec_priv && track->codec_priv_size > 0){
+ st->codec->extradata = av_malloc(track->codec_priv_size);
+ if(st->codec->extradata == NULL)
+ return AVERROR_NOMEM;
+ st->codec->extradata_size = track->codec_priv_size;
+ memcpy(st->codec->extradata, track->codec_priv,
+ track->codec_priv_size);
+ }
if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
MatroskaVideoTrack *videotrack = (MatroskaVideoTrack *)track;
- st->codec.codec_type = CODEC_TYPE_VIDEO;
- st->codec.codec_tag = videotrack->fourcc;
- st->codec.width = videotrack->pixel_width;
- st->codec.height = videotrack->pixel_height;
+ st->codec->codec_type = CODEC_TYPE_VIDEO;
+ st->codec->codec_tag = videotrack->fourcc;
+ st->codec->width = videotrack->pixel_width;
+ st->codec->height = videotrack->pixel_height;
if (videotrack->display_width == 0)
- st->codec.sample_aspect_ratio.num =
+ st->codec->sample_aspect_ratio.num =
videotrack->pixel_width;
else
- st->codec.sample_aspect_ratio.num =
+ st->codec->sample_aspect_ratio.num =
videotrack->display_width;
if (videotrack->display_height == 0)
- st->codec.sample_aspect_ratio.num =
+ st->codec->sample_aspect_ratio.num =
videotrack->pixel_height;
else
- st->codec.sample_aspect_ratio.num =
+ st->codec->sample_aspect_ratio.num =
videotrack->display_height;
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track;
- st->codec.codec_type = CODEC_TYPE_AUDIO;
- st->codec.sample_rate = audiotrack->samplerate;
- st->codec.channels = audiotrack->channels;
+ st->codec->codec_type = CODEC_TYPE_AUDIO;
+ st->codec->sample_rate = audiotrack->samplerate;
+ st->codec->channels = audiotrack->channels;
}
/* What do we do with private data? E.g. for Vorbis. */
uint32_t *lace_size = NULL;
int n, track, flags, laces = 0;
uint64_t num;
+ int64_t pos= url_ftell(&matroska->ctx->pb);
if ((res = ebml_read_binary(matroska, &id, &data, &size)) < 0)
break;
av_free(origdata);
break;
}
+ if(matroska->ctx->streams[ matroska->tracks[track]->stream_index ]->discard >= AVDISCARD_ALL){
+ av_free(origdata);
+ break;
+ }
/* time (relative to cluster time) */
time = ((data[0] << 8) | data[1]) * matroska->time_scale;
matroska->tracks[track]->stream_index;
pkt->pts = timecode / 1000000; /* ns to ms */
+ pkt->pos= pos;
matroska_queue_packet(matroska, pkt);
}
uint64_t cluster_time = 0;
av_log(matroska->ctx, AV_LOG_DEBUG,
- "parsing cluster at %lld\n", url_ftell(&matroska->ctx->pb));
+ "parsing cluster at %"PRId64"\n", url_ftell(&matroska->ctx->pb));
while (res == 0) {
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
av_free(track);
}
+ for (n = 0; n < s->nb_streams; n++) {
+ av_free(s->streams[n]->codec->extradata);
+ }
+
memset(matroska, 0, sizeof(MatroskaDemuxContext));
return 0;