mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
matroskadec: K&R formatting cosmetics
Also sort #includes into canonical order. Signed-off-by: Diego Biurrun <diego@biurrun.de>
This commit is contained in:
parent
77eed91fab
commit
84cfce9f99
@ -28,28 +28,33 @@
|
|||||||
* @see specs available on the Matroska project page: http://www.matroska.org/
|
* @see specs available on the Matroska project page: http://www.matroska.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "avformat.h"
|
|
||||||
#include "internal.h"
|
|
||||||
#include "avio_internal.h"
|
|
||||||
/* For ff_codec_get_id(). */
|
|
||||||
#include "riff.h"
|
|
||||||
#include "isom.h"
|
|
||||||
#include "rmsipr.h"
|
|
||||||
#include "matroska.h"
|
|
||||||
#include "libavcodec/bytestream.h"
|
|
||||||
#include "libavcodec/mpeg4audio.h"
|
|
||||||
#include "libavutil/intfloat.h"
|
|
||||||
#include "libavutil/intreadwrite.h"
|
|
||||||
#include "libavutil/avstring.h"
|
|
||||||
#include "libavutil/lzo.h"
|
|
||||||
#include "libavutil/dict.h"
|
|
||||||
#if CONFIG_ZLIB
|
|
||||||
#include <zlib.h>
|
|
||||||
#endif
|
|
||||||
#if CONFIG_BZLIB
|
#if CONFIG_BZLIB
|
||||||
#include <bzlib.h>
|
#include <bzlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_ZLIB
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libavutil/avstring.h"
|
||||||
|
#include "libavutil/dict.h"
|
||||||
|
#include "libavutil/intfloat.h"
|
||||||
|
#include "libavutil/intreadwrite.h"
|
||||||
|
#include "libavutil/lzo.h"
|
||||||
|
|
||||||
|
#include "libavcodec/bytestream.h"
|
||||||
|
#include "libavcodec/mpeg4audio.h"
|
||||||
|
|
||||||
|
#include "avformat.h"
|
||||||
|
#include "avio_internal.h"
|
||||||
|
#include "internal.h"
|
||||||
|
#include "isom.h"
|
||||||
|
#include "matroska.h"
|
||||||
|
/* For ff_codec_get_id(). */
|
||||||
|
#include "riff.h"
|
||||||
|
#include "rmsipr.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EBML_NONE,
|
EBML_NONE,
|
||||||
@ -581,6 +586,7 @@ static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos)
|
|||||||
}
|
}
|
||||||
id = (id << 8) | avio_r8(pb);
|
id = (id << 8) | avio_r8(pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
matroska->done = 1;
|
matroska->done = 1;
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
@ -692,13 +698,13 @@ static int ebml_read_uint(AVIOContext *pb, int size, uint64_t *num)
|
|||||||
*/
|
*/
|
||||||
static int ebml_read_float(AVIOContext *pb, int size, double *num)
|
static int ebml_read_float(AVIOContext *pb, int size, double *num)
|
||||||
{
|
{
|
||||||
if (size == 0) {
|
if (size == 0)
|
||||||
*num = 0;
|
*num = 0;
|
||||||
} else if (size == 4) {
|
else if (size == 4)
|
||||||
*num = av_int2float(avio_rb32(pb));
|
*num = av_int2float(avio_rb32(pb));
|
||||||
} else if (size == 8){
|
else if (size == 8)
|
||||||
*num = av_int2double(avio_rb64(pb));
|
*num = av_int2double(avio_rb64(pb));
|
||||||
} else
|
else
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -914,19 +920,31 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (syntax->type) {
|
switch (syntax->type) {
|
||||||
case EBML_UINT: res = ebml_read_uint (pb, length, data); break;
|
case EBML_UINT:
|
||||||
case EBML_FLOAT: res = ebml_read_float (pb, length, data); break;
|
res = ebml_read_uint(pb, length, data);
|
||||||
|
break;
|
||||||
|
case EBML_FLOAT:
|
||||||
|
res = ebml_read_float(pb, length, data);
|
||||||
|
break;
|
||||||
case EBML_STR:
|
case EBML_STR:
|
||||||
case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break;
|
case EBML_UTF8:
|
||||||
case EBML_BIN: res = ebml_read_binary(pb, length, data); break;
|
res = ebml_read_ascii(pb, length, data);
|
||||||
case EBML_NEST: if ((res=ebml_read_master(matroska, length)) < 0)
|
break;
|
||||||
|
case EBML_BIN:
|
||||||
|
res = ebml_read_binary(pb, length, data);
|
||||||
|
break;
|
||||||
|
case EBML_NEST:
|
||||||
|
if ((res = ebml_read_master(matroska, length)) < 0)
|
||||||
return res;
|
return res;
|
||||||
if (id == MATROSKA_ID_SEGMENT)
|
if (id == MATROSKA_ID_SEGMENT)
|
||||||
matroska->segment_start = avio_tell(matroska->ctx->pb);
|
matroska->segment_start = avio_tell(matroska->ctx->pb);
|
||||||
return ebml_parse_nest(matroska, syntax->def.n, data);
|
return ebml_parse_nest(matroska, syntax->def.n, data);
|
||||||
case EBML_PASS: return ebml_parse_id(matroska, syntax->def.n, id, data);
|
case EBML_PASS:
|
||||||
case EBML_STOP: return 1;
|
return ebml_parse_id(matroska, syntax->def.n, id, data);
|
||||||
default: return avio_skip(pb,length)<0 ? AVERROR(EIO) : 0;
|
case EBML_STOP:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return avio_skip(pb, length) < 0 ? AVERROR(EIO) : 0;
|
||||||
}
|
}
|
||||||
if (res == AVERROR_INVALIDDATA)
|
if (res == AVERROR_INVALIDDATA)
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n");
|
av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n");
|
||||||
@ -942,23 +960,28 @@ static void ebml_free(EbmlSyntax *syntax, void *data)
|
|||||||
void *data_off = (char *) data + syntax[i].data_offset;
|
void *data_off = (char *) data + syntax[i].data_offset;
|
||||||
switch (syntax[i].type) {
|
switch (syntax[i].type) {
|
||||||
case EBML_STR:
|
case EBML_STR:
|
||||||
case EBML_UTF8: av_freep(data_off); break;
|
case EBML_UTF8:
|
||||||
case EBML_BIN: av_freep(&((EbmlBin *)data_off)->data); break;
|
av_freep(data_off);
|
||||||
|
break;
|
||||||
|
case EBML_BIN:
|
||||||
|
av_freep(&((EbmlBin *) data_off)->data);
|
||||||
|
break;
|
||||||
case EBML_NEST:
|
case EBML_NEST:
|
||||||
if (syntax[i].list_elem_size) {
|
if (syntax[i].list_elem_size) {
|
||||||
EbmlList *list = data_off;
|
EbmlList *list = data_off;
|
||||||
char *ptr = list->elem;
|
char *ptr = list->elem;
|
||||||
for (j=0; j<list->nb_elem; j++, ptr+=syntax[i].list_elem_size)
|
for (j = 0; j < list->nb_elem;
|
||||||
|
j++, ptr += syntax[i].list_elem_size)
|
||||||
ebml_free(syntax[i].def.n, ptr);
|
ebml_free(syntax[i].def.n, ptr);
|
||||||
av_free(list->elem);
|
av_free(list->elem);
|
||||||
} else
|
} else
|
||||||
ebml_free(syntax[i].def.n, data_off);
|
ebml_free(syntax[i].def.n, data_off);
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Autodetecting...
|
* Autodetecting...
|
||||||
*/
|
*/
|
||||||
@ -1034,7 +1057,8 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
|
|||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
switch (encodings[0].compression.algo) {
|
switch (encodings[0].compression.algo) {
|
||||||
case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: {
|
case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP:
|
||||||
|
{
|
||||||
int header_size = encodings[0].compression.settings.size;
|
int header_size = encodings[0].compression.settings.size;
|
||||||
uint8_t *header = encodings[0].compression.settings.data;
|
uint8_t *header = encodings[0].compression.settings.data;
|
||||||
|
|
||||||
@ -1070,7 +1094,8 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_ZLIB
|
#if CONFIG_ZLIB
|
||||||
case MATROSKA_TRACK_ENCODING_COMP_ZLIB: {
|
case MATROSKA_TRACK_ENCODING_COMP_ZLIB:
|
||||||
|
{
|
||||||
z_stream zstream = { 0 };
|
z_stream zstream = { 0 };
|
||||||
if (inflateInit(&zstream) != Z_OK)
|
if (inflateInit(&zstream) != Z_OK)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1101,7 +1126,8 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_BZLIB
|
#if CONFIG_BZLIB
|
||||||
case MATROSKA_TRACK_ENCODING_COMP_BZLIB: {
|
case MATROSKA_TRACK_ENCODING_COMP_BZLIB:
|
||||||
|
{
|
||||||
bz_stream bzstream = { 0 };
|
bz_stream bzstream = { 0 };
|
||||||
if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)
|
if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1138,6 +1164,7 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
|
|||||||
*buf = pkt_data;
|
*buf = pkt_data;
|
||||||
*buf_size = pkt_size;
|
*buf_size = pkt_size;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
av_free(pkt_data);
|
av_free(pkt_data);
|
||||||
return result;
|
return result;
|
||||||
@ -1148,26 +1175,36 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,
|
|||||||
{
|
{
|
||||||
AVBufferRef *line;
|
AVBufferRef *line;
|
||||||
char *layer, *ptr = pkt->data, *end = ptr + pkt->size;
|
char *layer, *ptr = pkt->data, *end = ptr + pkt->size;
|
||||||
for (; *ptr!=',' && ptr<end-1; ptr++);
|
|
||||||
|
for (; *ptr != ',' && ptr < end - 1; ptr++)
|
||||||
|
;
|
||||||
if (*ptr == ',')
|
if (*ptr == ',')
|
||||||
layer = ++ptr;
|
layer = ++ptr;
|
||||||
for (; *ptr!=',' && ptr<end-1; ptr++);
|
for (; *ptr != ',' && ptr < end - 1; ptr++)
|
||||||
|
;
|
||||||
if (*ptr == ',') {
|
if (*ptr == ',') {
|
||||||
int64_t end_pts = pkt->pts + display_duration;
|
int64_t end_pts = pkt->pts + display_duration;
|
||||||
int sc = matroska->time_scale * pkt->pts / 10000000;
|
int sc = matroska->time_scale * pkt->pts / 10000000;
|
||||||
int ec = matroska->time_scale * end_pts / 10000000;
|
int ec = matroska->time_scale * end_pts / 10000000;
|
||||||
int sh, sm, ss, eh, em, es, len;
|
int sh, sm, ss, eh, em, es, len;
|
||||||
sh = sc/360000; sc -= 360000*sh;
|
sh = sc / 360000;
|
||||||
sm = sc/ 6000; sc -= 6000*sm;
|
sc -= 360000 * sh;
|
||||||
ss = sc/ 100; sc -= 100*ss;
|
sm = sc / 6000;
|
||||||
eh = ec/360000; ec -= 360000*eh;
|
sc -= 6000 * sm;
|
||||||
em = ec/ 6000; ec -= 6000*em;
|
ss = sc / 100;
|
||||||
es = ec/ 100; ec -= 100*es;
|
sc -= 100 * ss;
|
||||||
|
eh = ec / 360000;
|
||||||
|
ec -= 360000 * eh;
|
||||||
|
em = ec / 6000;
|
||||||
|
ec -= 6000 * em;
|
||||||
|
es = ec / 100;
|
||||||
|
ec -= 100 * es;
|
||||||
*ptr++ = '\0';
|
*ptr++ = '\0';
|
||||||
len = 50 + end - ptr + FF_INPUT_BUFFER_PADDING_SIZE;
|
len = 50 + end - ptr + FF_INPUT_BUFFER_PADDING_SIZE;
|
||||||
if (!(line = av_buffer_alloc(len)))
|
if (!(line = av_buffer_alloc(len)))
|
||||||
return;
|
return;
|
||||||
snprintf(line->data, len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n",
|
snprintf(line->data, len,
|
||||||
|
"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n",
|
||||||
layer, sh, sm, ss, sc, eh, em, es, ec, ptr);
|
layer, sh, sm, ss, sc, eh, em, es, ec, ptr);
|
||||||
av_buffer_unref(&pkt->buf);
|
av_buffer_unref(&pkt->buf);
|
||||||
pkt->buf = line;
|
pkt->buf = line;
|
||||||
@ -1198,15 +1235,17 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < list->nb_elem; i++) {
|
for (i = 0; i < list->nb_elem; i++) {
|
||||||
const char *lang = tags[i].lang && strcmp(tags[i].lang, "und") ?
|
const char *lang = tags[i].lang &&
|
||||||
tags[i].lang : NULL;
|
strcmp(tags[i].lang, "und") ? tags[i].lang : NULL;
|
||||||
|
|
||||||
if (!tags[i].name) {
|
if (!tags[i].name) {
|
||||||
av_log(s, AV_LOG_WARNING, "Skipping invalid tag with no TagName.\n");
|
av_log(s, AV_LOG_WARNING, "Skipping invalid tag with no TagName.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (prefix) snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name);
|
if (prefix)
|
||||||
else av_strlcpy(key, tags[i].name, sizeof(key));
|
snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name);
|
||||||
|
else
|
||||||
|
av_strlcpy(key, tags[i].name, sizeof(key));
|
||||||
if (tags[i].def || !lang) {
|
if (tags[i].def || !lang) {
|
||||||
av_dict_set(metadata, key, tags[i].string, 0);
|
av_dict_set(metadata, key, tags[i].string, 0);
|
||||||
if (tags[i].sub.nb_elem)
|
if (tags[i].sub.nb_elem)
|
||||||
@ -1233,15 +1272,15 @@ static void matroska_convert_tags(AVFormatContext *s)
|
|||||||
if (tags[i].target.attachuid) {
|
if (tags[i].target.attachuid) {
|
||||||
MatroskaAttachement *attachment = matroska->attachments.elem;
|
MatroskaAttachement *attachment = matroska->attachments.elem;
|
||||||
for (j = 0; j < matroska->attachments.nb_elem; j++)
|
for (j = 0; j < matroska->attachments.nb_elem; j++)
|
||||||
if (attachment[j].uid == tags[i].target.attachuid
|
if (attachment[j].uid == tags[i].target.attachuid &&
|
||||||
&& attachment[j].stream)
|
attachment[j].stream)
|
||||||
matroska_convert_tag(s, &tags[i].tag,
|
matroska_convert_tag(s, &tags[i].tag,
|
||||||
&attachment[j].stream->metadata, NULL);
|
&attachment[j].stream->metadata, NULL);
|
||||||
} else if (tags[i].target.chapteruid) {
|
} else if (tags[i].target.chapteruid) {
|
||||||
MatroskaChapter *chapter = matroska->chapters.elem;
|
MatroskaChapter *chapter = matroska->chapters.elem;
|
||||||
for (j = 0; j < matroska->chapters.nb_elem; j++)
|
for (j = 0; j < matroska->chapters.nb_elem; j++)
|
||||||
if (chapter[j].uid == tags[i].target.chapteruid
|
if (chapter[j].uid == tags[i].target.chapteruid &&
|
||||||
&& chapter[j].chapter)
|
chapter[j].chapter)
|
||||||
matroska_convert_tag(s, &tags[i].tag,
|
matroska_convert_tag(s, &tags[i].tag,
|
||||||
&chapter[j].chapter->metadata, NULL);
|
&chapter[j].chapter->metadata, NULL);
|
||||||
} else if (tags[i].target.trackuid) {
|
} else if (tags[i].target.trackuid) {
|
||||||
@ -1257,20 +1296,21 @@ static void matroska_convert_tags(AVFormatContext *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, int idx)
|
static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska,
|
||||||
|
int idx)
|
||||||
{
|
{
|
||||||
EbmlList *seekhead_list = &matroska->seekhead;
|
EbmlList *seekhead_list = &matroska->seekhead;
|
||||||
MatroskaSeekhead *seekhead = seekhead_list->elem;
|
|
||||||
uint32_t level_up = matroska->level_up;
|
uint32_t level_up = matroska->level_up;
|
||||||
int64_t before_pos = avio_tell(matroska->ctx->pb);
|
|
||||||
uint32_t saved_id = matroska->current_id;
|
uint32_t saved_id = matroska->current_id;
|
||||||
|
MatroskaSeekhead *seekhead = seekhead_list->elem;
|
||||||
|
int64_t before_pos = avio_tell(matroska->ctx->pb);
|
||||||
MatroskaLevel level;
|
MatroskaLevel level;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (idx >= seekhead_list->nb_elem
|
if (idx >= seekhead_list->nb_elem ||
|
||||||
|| seekhead[idx].id == MATROSKA_ID_SEEKHEAD
|
seekhead[idx].id == MATROSKA_ID_SEEKHEAD ||
|
||||||
|| seekhead[idx].id == MATROSKA_ID_CLUSTER)
|
seekhead[idx].id == MATROSKA_ID_CLUSTER)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* seek */
|
/* seek */
|
||||||
@ -1335,7 +1375,8 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
|
static void matroska_parse_cues(MatroskaDemuxContext *matroska)
|
||||||
|
{
|
||||||
EbmlList *seekhead_list = &matroska->seekhead;
|
EbmlList *seekhead_list = &matroska->seekhead;
|
||||||
MatroskaSeekhead *seekhead = seekhead_list->elem;
|
MatroskaSeekhead *seekhead = seekhead_list->elem;
|
||||||
EbmlList *index_list;
|
EbmlList *index_list;
|
||||||
@ -1352,8 +1393,8 @@ static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
|
|||||||
|
|
||||||
index_list = &matroska->index;
|
index_list = &matroska->index;
|
||||||
index = index_list->elem;
|
index = index_list->elem;
|
||||||
if (index_list->nb_elem
|
if (index_list->nb_elem &&
|
||||||
&& index[0].time > 1E14/matroska->time_scale) {
|
index[0].time > 1E14 / matroska->time_scale) {
|
||||||
av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
|
av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
|
||||||
index_scale = matroska->time_scale;
|
index_scale = matroska->time_scale;
|
||||||
}
|
}
|
||||||
@ -1361,7 +1402,8 @@ static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
|
|||||||
EbmlList *pos_list = &index[i].pos;
|
EbmlList *pos_list = &index[i].pos;
|
||||||
MatroskaIndexPos *pos = pos_list->elem;
|
MatroskaIndexPos *pos = pos_list->elem;
|
||||||
for (j = 0; j < pos_list->nb_elem; j++) {
|
for (j = 0; j < pos_list->nb_elem; j++) {
|
||||||
MatroskaTrack *track = matroska_find_track_by_num(matroska, pos[j].track);
|
MatroskaTrack *track = matroska_find_track_by_num(matroska,
|
||||||
|
pos[j].track);
|
||||||
if (track && track->stream)
|
if (track && track->stream)
|
||||||
av_add_index_entry(track->stream,
|
av_add_index_entry(track->stream,
|
||||||
pos[j].pos + matroska->segment_start,
|
pos[j].pos + matroska->segment_start,
|
||||||
@ -1396,8 +1438,8 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
{
|
{
|
||||||
MatroskaDemuxContext *matroska = s->priv_data;
|
MatroskaDemuxContext *matroska = s->priv_data;
|
||||||
EbmlList *attachements_list = &matroska->attachments;
|
EbmlList *attachements_list = &matroska->attachments;
|
||||||
MatroskaAttachement *attachements;
|
|
||||||
EbmlList *chapters_list = &matroska->chapters;
|
EbmlList *chapters_list = &matroska->chapters;
|
||||||
|
MatroskaAttachement *attachements;
|
||||||
MatroskaChapter *chapters;
|
MatroskaChapter *chapters;
|
||||||
MatroskaTrack *tracks;
|
MatroskaTrack *tracks;
|
||||||
uint64_t max_start = 0;
|
uint64_t max_start = 0;
|
||||||
@ -1409,9 +1451,11 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
matroska->ctx = s;
|
matroska->ctx = s;
|
||||||
|
|
||||||
/* First read the EBML header. */
|
/* First read the EBML header. */
|
||||||
if (ebml_parse(matroska, ebml_syntax, &ebml)
|
if (ebml_parse(matroska, ebml_syntax, &ebml) ||
|
||||||
|| ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
|
ebml.version > EBML_VERSION ||
|
||||||
|| ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) {
|
ebml.max_size > sizeof(uint64_t) ||
|
||||||
|
ebml.id_length > sizeof(uint32_t) ||
|
||||||
|
ebml.doctype_version > 2) {
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR,
|
av_log(matroska->ctx, AV_LOG_ERROR,
|
||||||
"EBML header using unsupported features\n"
|
"EBML header using unsupported features\n"
|
||||||
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
|
"(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
|
||||||
@ -1447,8 +1491,8 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
if (!matroska->time_scale)
|
if (!matroska->time_scale)
|
||||||
matroska->time_scale = 1000000;
|
matroska->time_scale = 1000000;
|
||||||
if (matroska->duration)
|
if (matroska->duration)
|
||||||
matroska->ctx->duration = matroska->duration * matroska->time_scale
|
matroska->ctx->duration = matroska->duration * matroska->time_scale *
|
||||||
* 1000 / AV_TIME_BASE;
|
1000 / AV_TIME_BASE;
|
||||||
av_dict_set(&s->metadata, "title", matroska->title, 0);
|
av_dict_set(&s->metadata, "title", matroska->title, 0);
|
||||||
|
|
||||||
tracks = matroska->tracks.elem;
|
tracks = matroska->tracks.elem;
|
||||||
@ -1533,42 +1577,58 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC")
|
if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") &&
|
||||||
&& track->codec_priv.size >= 40
|
track->codec_priv.size >= 40 &&
|
||||||
&& track->codec_priv.data != NULL) {
|
track->codec_priv.data != NULL) {
|
||||||
track->ms_compat = 1;
|
track->ms_compat = 1;
|
||||||
track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
|
track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
|
||||||
codec_id = ff_codec_get_id(ff_codec_bmp_tags, track->video.fourcc);
|
codec_id = ff_codec_get_id(ff_codec_bmp_tags,
|
||||||
|
track->video.fourcc);
|
||||||
extradata_offset = 40;
|
extradata_offset = 40;
|
||||||
} else if (!strcmp(track->codec_id, "A_MS/ACM")
|
} else if (!strcmp(track->codec_id, "A_MS/ACM") &&
|
||||||
&& track->codec_priv.size >= 14
|
track->codec_priv.size >= 14 &&
|
||||||
&& track->codec_priv.data != NULL) {
|
track->codec_priv.data != NULL) {
|
||||||
int ret;
|
int ret;
|
||||||
ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size,
|
ffio_init_context(&b, track->codec_priv.data,
|
||||||
|
track->codec_priv.size,
|
||||||
0, NULL, NULL, NULL, NULL);
|
0, NULL, NULL, NULL, NULL);
|
||||||
ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size);
|
ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
codec_id = st->codec->codec_id;
|
codec_id = st->codec->codec_id;
|
||||||
extradata_offset = FFMIN(track->codec_priv.size, 18);
|
extradata_offset = FFMIN(track->codec_priv.size, 18);
|
||||||
} else if (!strcmp(track->codec_id, "V_QUICKTIME")
|
} else if (!strcmp(track->codec_id, "V_QUICKTIME") &&
|
||||||
&& (track->codec_priv.size >= 86)
|
(track->codec_priv.size >= 86) &&
|
||||||
&& (track->codec_priv.data != NULL)) {
|
(track->codec_priv.data != NULL)) {
|
||||||
track->video.fourcc = AV_RL32(track->codec_priv.data);
|
track->video.fourcc = AV_RL32(track->codec_priv.data);
|
||||||
codec_id=ff_codec_get_id(ff_codec_movvideo_tags, track->video.fourcc);
|
codec_id = ff_codec_get_id(ff_codec_movvideo_tags,
|
||||||
|
track->video.fourcc);
|
||||||
} else if (codec_id == AV_CODEC_ID_PCM_S16BE) {
|
} else if (codec_id == AV_CODEC_ID_PCM_S16BE) {
|
||||||
switch (track->audio.bitdepth) {
|
switch (track->audio.bitdepth) {
|
||||||
case 8: codec_id = AV_CODEC_ID_PCM_U8; break;
|
case 8:
|
||||||
case 24: codec_id = AV_CODEC_ID_PCM_S24BE; break;
|
codec_id = AV_CODEC_ID_PCM_U8;
|
||||||
case 32: codec_id = AV_CODEC_ID_PCM_S32BE; break;
|
break;
|
||||||
|
case 24:
|
||||||
|
codec_id = AV_CODEC_ID_PCM_S24BE;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
codec_id = AV_CODEC_ID_PCM_S32BE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (codec_id == AV_CODEC_ID_PCM_S16LE) {
|
} else if (codec_id == AV_CODEC_ID_PCM_S16LE) {
|
||||||
switch (track->audio.bitdepth) {
|
switch (track->audio.bitdepth) {
|
||||||
case 8: codec_id = AV_CODEC_ID_PCM_U8; break;
|
case 8:
|
||||||
case 24: codec_id = AV_CODEC_ID_PCM_S24LE; break;
|
codec_id = AV_CODEC_ID_PCM_U8;
|
||||||
case 32: codec_id = AV_CODEC_ID_PCM_S32LE; break;
|
break;
|
||||||
|
case 24:
|
||||||
|
codec_id = AV_CODEC_ID_PCM_S24LE;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
codec_id = AV_CODEC_ID_PCM_S32LE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (codec_id==AV_CODEC_ID_PCM_F32LE && track->audio.bitdepth==64) {
|
} else if (codec_id == AV_CODEC_ID_PCM_F32LE &&
|
||||||
|
track->audio.bitdepth == 64) {
|
||||||
codec_id = AV_CODEC_ID_PCM_F64LE;
|
codec_id = AV_CODEC_ID_PCM_F64LE;
|
||||||
} else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) {
|
} else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) {
|
||||||
int profile = matroska_aac_profile(track->codec_id);
|
int profile = matroska_aac_profile(track->codec_id);
|
||||||
@ -1588,10 +1648,11 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
extradata_size = 2;
|
extradata_size = 2;
|
||||||
} else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size) {
|
} else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size) {
|
||||||
/* Only ALAC's magic cookie is stored in Matroska's track headers.
|
/* Only ALAC's magic cookie is stored in Matroska's track headers.
|
||||||
Create the "atom size", "tag", and "tag version" fields the
|
* Create the "atom size", "tag", and "tag version" fields the
|
||||||
decoder expects manually. */
|
* decoder expects manually. */
|
||||||
extradata_size = 12 + track->codec_priv.size;
|
extradata_size = 12 + track->codec_priv.size;
|
||||||
extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
extradata = av_mallocz(extradata_size +
|
||||||
|
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (extradata == NULL)
|
if (extradata == NULL)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
AV_WB32(extradata, extradata_size);
|
AV_WB32(extradata, extradata_size);
|
||||||
@ -1611,17 +1672,23 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
avio_wl16(&b, track->audio.channels);
|
avio_wl16(&b, track->audio.channels);
|
||||||
avio_wl16(&b, track->audio.bitdepth);
|
avio_wl16(&b, track->audio.bitdepth);
|
||||||
avio_wl32(&b, track->audio.out_samplerate);
|
avio_wl32(&b, track->audio.out_samplerate);
|
||||||
avio_wl32(&b, matroska->ctx->duration * track->audio.out_samplerate);
|
avio_wl32(&b, matroska->ctx->duration *
|
||||||
} else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 ||
|
track->audio.out_samplerate);
|
||||||
codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) {
|
} else if (codec_id == AV_CODEC_ID_RV10 ||
|
||||||
|
codec_id == AV_CODEC_ID_RV20 ||
|
||||||
|
codec_id == AV_CODEC_ID_RV30 ||
|
||||||
|
codec_id == AV_CODEC_ID_RV40) {
|
||||||
extradata_offset = 26;
|
extradata_offset = 26;
|
||||||
} else if (codec_id == AV_CODEC_ID_RA_144) {
|
} else if (codec_id == AV_CODEC_ID_RA_144) {
|
||||||
track->audio.out_samplerate = 8000;
|
track->audio.out_samplerate = 8000;
|
||||||
track->audio.channels = 1;
|
track->audio.channels = 1;
|
||||||
} else if (codec_id == AV_CODEC_ID_RA_288 || codec_id == AV_CODEC_ID_COOK ||
|
} else if (codec_id == AV_CODEC_ID_RA_288 ||
|
||||||
codec_id == AV_CODEC_ID_ATRAC3 || codec_id == AV_CODEC_ID_SIPR) {
|
codec_id == AV_CODEC_ID_COOK ||
|
||||||
|
codec_id == AV_CODEC_ID_ATRAC3 ||
|
||||||
|
codec_id == AV_CODEC_ID_SIPR) {
|
||||||
int flavor;
|
int flavor;
|
||||||
ffio_init_context(&b, track->codec_priv.data,track->codec_priv.size,
|
ffio_init_context(&b, track->codec_priv.data,
|
||||||
|
track->codec_priv.size,
|
||||||
0, NULL, NULL, NULL, NULL);
|
0, NULL, NULL, NULL, NULL);
|
||||||
avio_skip(&b, 22);
|
avio_skip(&b, 22);
|
||||||
flavor = avio_rb16(&b);
|
flavor = avio_rb16(&b);
|
||||||
@ -1630,11 +1697,14 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
track->audio.sub_packet_h = avio_rb16(&b);
|
track->audio.sub_packet_h = avio_rb16(&b);
|
||||||
track->audio.frame_size = avio_rb16(&b);
|
track->audio.frame_size = avio_rb16(&b);
|
||||||
track->audio.sub_packet_size = avio_rb16(&b);
|
track->audio.sub_packet_size = avio_rb16(&b);
|
||||||
if (flavor <= 0 || track->audio.coded_framesize <= 0 ||
|
if (flavor <= 0 ||
|
||||||
track->audio.sub_packet_h <= 0 || track->audio.frame_size <= 0 ||
|
track->audio.coded_framesize <= 0 ||
|
||||||
|
track->audio.sub_packet_h <= 0 ||
|
||||||
|
track->audio.frame_size <= 0 ||
|
||||||
track->audio.sub_packet_size <= 0)
|
track->audio.sub_packet_size <= 0)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h);
|
track->audio.buf = av_malloc(track->audio.frame_size *
|
||||||
|
track->audio.sub_packet_h);
|
||||||
if (codec_id == AV_CODEC_ID_RA_288) {
|
if (codec_id == AV_CODEC_ID_RA_288) {
|
||||||
st->codec->block_align = track->audio.coded_framesize;
|
st->codec->block_align = track->audio.coded_framesize;
|
||||||
track->codec_priv.size = 0;
|
track->codec_priv.size = 0;
|
||||||
@ -1656,7 +1726,8 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
|
|
||||||
if (track->time_scale < 0.01)
|
if (track->time_scale < 0.01)
|
||||||
track->time_scale = 1.0;
|
track->time_scale = 1.0;
|
||||||
avpriv_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
|
avpriv_set_pts_info(st, 64, matroska->time_scale * track->time_scale,
|
||||||
|
1000 * 1000 * 1000); /* 64 bit pts in ns */
|
||||||
|
|
||||||
st->codec->codec_id = codec_id;
|
st->codec->codec_id = codec_id;
|
||||||
st->start_time = 0;
|
st->start_time = 0;
|
||||||
@ -1732,7 +1803,8 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
if (st->codec->extradata == NULL)
|
if (st->codec->extradata == NULL)
|
||||||
break;
|
break;
|
||||||
st->codec->extradata_size = attachements[j].bin.size;
|
st->codec->extradata_size = attachements[j].bin.size;
|
||||||
memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size);
|
memcpy(st->codec->extradata, attachements[j].bin.data,
|
||||||
|
attachements[j].bin.size);
|
||||||
|
|
||||||
for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
|
for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
|
||||||
if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime,
|
if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime,
|
||||||
@ -1747,10 +1819,11 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
|
|
||||||
chapters = chapters_list->elem;
|
chapters = chapters_list->elem;
|
||||||
for (i = 0; i < chapters_list->nb_elem; i++)
|
for (i = 0; i < chapters_list->nb_elem; i++)
|
||||||
if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid
|
if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid &&
|
||||||
&& (max_start==0 || chapters[i].start > max_start)) {
|
(max_start == 0 || chapters[i].start > max_start)) {
|
||||||
chapters[i].chapter =
|
chapters[i].chapter =
|
||||||
avpriv_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
|
avpriv_new_chapter(s, chapters[i].uid,
|
||||||
|
(AVRational) { 1, 1000000000 },
|
||||||
chapters[i].start, chapters[i].end,
|
chapters[i].start, chapters[i].end,
|
||||||
chapters[i].title);
|
chapters[i].title);
|
||||||
av_dict_set(&chapters[i].chapter->metadata,
|
av_dict_set(&chapters[i].chapter->metadata,
|
||||||
@ -1778,7 +1851,8 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
|
|||||||
memmove(&matroska->packets[0], &matroska->packets[1],
|
memmove(&matroska->packets[0], &matroska->packets[1],
|
||||||
(matroska->num_packets - 1) * sizeof(AVPacket *));
|
(matroska->num_packets - 1) * sizeof(AVPacket *));
|
||||||
newpackets = av_realloc(matroska->packets,
|
newpackets = av_realloc(matroska->packets,
|
||||||
(matroska->num_packets - 1) * sizeof(AVPacket *));
|
(matroska->num_packets - 1) *
|
||||||
|
sizeof(AVPacket *));
|
||||||
if (newpackets)
|
if (newpackets)
|
||||||
matroska->packets = newpackets;
|
matroska->packets = newpackets;
|
||||||
} else {
|
} else {
|
||||||
@ -1836,7 +1910,8 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0x1: /* Xiph lacing */ {
|
case 0x1: /* Xiph lacing */
|
||||||
|
{
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
uint32_t total = 0;
|
uint32_t total = 0;
|
||||||
for (n = 0; res == 0 && n < *laces - 1; n++) {
|
for (n = 0; res == 0 && n < *laces - 1; n++) {
|
||||||
@ -1872,7 +1947,8 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
|
|||||||
lace_size[n] = size / *laces;
|
lace_size[n] = size / *laces;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3: /* EBML lacing */ {
|
case 0x3: /* EBML lacing */
|
||||||
|
{
|
||||||
uint64_t num;
|
uint64_t num;
|
||||||
uint64_t total;
|
uint64_t total;
|
||||||
n = matroska_ebmlnum_uint(matroska, data, size, &num);
|
n = matroska_ebmlnum_uint(matroska, data, size, &num);
|
||||||
@ -1917,11 +1993,9 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
|
static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
|
||||||
MatroskaTrack *track,
|
MatroskaTrack *track, AVStream *st,
|
||||||
AVStream *st,
|
uint8_t *data, int size, uint64_t timecode,
|
||||||
uint8_t *data, int size,
|
uint64_t duration, int64_t pos)
|
||||||
uint64_t timecode, uint64_t duration,
|
|
||||||
int64_t pos)
|
|
||||||
{
|
{
|
||||||
int a = st->codec->block_align;
|
int a = st->codec->block_align;
|
||||||
int sps = track->audio.sub_packet_size;
|
int sps = track->audio.sub_packet_size;
|
||||||
@ -1957,7 +2031,9 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
|
|||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
for (x = 0; x < w / sps; x++)
|
for (x = 0; x < w / sps; x++)
|
||||||
memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);
|
memcpy(track->audio.buf +
|
||||||
|
sps * (h * x + ((h + 1) / 2) * (y & 1) + (y >> 1)),
|
||||||
|
data + x * sps, sps);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++track->audio.sub_packet_cnt >= h) {
|
if (++track->audio.sub_packet_cnt >= h) {
|
||||||
@ -1971,8 +2047,9 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
|
|||||||
while (track->audio.pkt_cnt) {
|
while (track->audio.pkt_cnt) {
|
||||||
AVPacket *pkt = av_mallocz(sizeof(AVPacket));
|
AVPacket *pkt = av_mallocz(sizeof(AVPacket));
|
||||||
av_new_packet(pkt, a);
|
av_new_packet(pkt, a);
|
||||||
memcpy(pkt->data, track->audio.buf
|
memcpy(pkt->data,
|
||||||
+ a * (h*w / a - track->audio.pkt_cnt--), a);
|
track->audio.buf + a * (h * w / a - track->audio.pkt_cnt--),
|
||||||
|
a);
|
||||||
pkt->pts = track->audio.buf_timecode;
|
pkt->pts = track->audio.buf_timecode;
|
||||||
track->audio.buf_timecode = AV_NOPTS_VALUE;
|
track->audio.buf_timecode = AV_NOPTS_VALUE;
|
||||||
pkt->pos = pos;
|
pkt->pos = pos;
|
||||||
@ -2065,8 +2142,7 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int matroska_parse_frame(MatroskaDemuxContext *matroska,
|
static int matroska_parse_frame(MatroskaDemuxContext *matroska,
|
||||||
MatroskaTrack *track,
|
MatroskaTrack *track, AVStream *st,
|
||||||
AVStream *st,
|
|
||||||
uint8_t *data, int pkt_size,
|
uint8_t *data, int pkt_size,
|
||||||
uint64_t timecode, uint64_t duration,
|
uint64_t timecode, uint64_t duration,
|
||||||
int64_t pos, int is_keyframe)
|
int64_t pos, int is_keyframe)
|
||||||
@ -2086,7 +2162,8 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
|
|||||||
uint8_t *wv_data;
|
uint8_t *wv_data;
|
||||||
res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size);
|
res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
av_log(matroska->ctx, AV_LOG_ERROR, "Error parsing a wavpack block.\n");
|
av_log(matroska->ctx, AV_LOG_ERROR,
|
||||||
|
"Error parsing a wavpack block.\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (pkt_data != data)
|
if (pkt_data != data)
|
||||||
@ -2143,6 +2220,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (pkt_data != data)
|
if (pkt_data != data)
|
||||||
av_freep(&pkt_data);
|
av_freep(&pkt_data);
|
||||||
@ -2188,17 +2266,19 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
|||||||
if (is_keyframe == -1)
|
if (is_keyframe == -1)
|
||||||
is_keyframe = flags & 0x80 ? AV_PKT_FLAG_KEY : 0;
|
is_keyframe = flags & 0x80 ? AV_PKT_FLAG_KEY : 0;
|
||||||
|
|
||||||
if (cluster_time != (uint64_t)-1
|
if (cluster_time != (uint64_t) -1 &&
|
||||||
&& (block_time >= 0 || cluster_time >= -block_time)) {
|
(block_time >= 0 || cluster_time >= -block_time)) {
|
||||||
timecode = cluster_time + block_time;
|
timecode = cluster_time + block_time;
|
||||||
if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE
|
if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE &&
|
||||||
&& timecode < track->end_timecode)
|
timecode < track->end_timecode)
|
||||||
is_keyframe = 0; /* overlapping subtitles are not key frame */
|
is_keyframe = 0; /* overlapping subtitles are not key frame */
|
||||||
if (is_keyframe)
|
if (is_keyframe)
|
||||||
av_add_index_entry(st, cluster_pos, timecode, 0,0,AVINDEX_KEYFRAME);
|
av_add_index_entry(st, cluster_pos, timecode, 0, 0,
|
||||||
|
AVINDEX_KEYFRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
|
if (matroska->skip_to_keyframe &&
|
||||||
|
track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
|
||||||
if (!is_keyframe || timecode < matroska->skip_to_timecode)
|
if (!is_keyframe || timecode < matroska->skip_to_timecode)
|
||||||
return res;
|
return res;
|
||||||
matroska->skip_to_keyframe = 0;
|
matroska->skip_to_keyframe = 0;
|
||||||
@ -2231,17 +2311,15 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
|||||||
st->codec->codec_id == AV_CODEC_ID_SIPR ||
|
st->codec->codec_id == AV_CODEC_ID_SIPR ||
|
||||||
st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&
|
st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&
|
||||||
st->codec->block_align && track->audio.sub_packet_size) {
|
st->codec->block_align && track->audio.sub_packet_size) {
|
||||||
|
|
||||||
res = matroska_parse_rm_audio(matroska, track, st, data,
|
res = matroska_parse_rm_audio(matroska, track, st, data,
|
||||||
lace_size[n],
|
lace_size[n],
|
||||||
timecode, duration, pos);
|
timecode, duration, pos);
|
||||||
if (res)
|
if (res)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
|
res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
|
||||||
timecode, duration,
|
timecode, duration, pos,
|
||||||
pos, !n? is_keyframe : 0);
|
!n ? is_keyframe : 0);
|
||||||
if (res)
|
if (res)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -2298,16 +2376,16 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
|
|||||||
int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
|
int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
|
||||||
if (!blocks[i].non_simple)
|
if (!blocks[i].non_simple)
|
||||||
blocks[i].duration = AV_NOPTS_VALUE;
|
blocks[i].duration = AV_NOPTS_VALUE;
|
||||||
res = matroska_parse_block(matroska,
|
res = matroska_parse_block(matroska, blocks[i].bin.data,
|
||||||
blocks[i].bin.data, blocks[i].bin.size,
|
blocks[i].bin.size, blocks[i].bin.pos,
|
||||||
blocks[i].bin.pos,
|
|
||||||
matroska->current_cluster.timecode,
|
matroska->current_cluster.timecode,
|
||||||
blocks[i].duration, is_keyframe,
|
blocks[i].duration, is_keyframe,
|
||||||
matroska->current_cluster_pos);
|
matroska->current_cluster_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0) matroska->done = 1;
|
if (res < 0)
|
||||||
|
matroska->done = 1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2318,6 +2396,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
|
|||||||
MatroskaBlock *blocks;
|
MatroskaBlock *blocks;
|
||||||
int i, res;
|
int i, res;
|
||||||
int64_t pos;
|
int64_t pos;
|
||||||
|
|
||||||
if (!matroska->contains_ssa)
|
if (!matroska->contains_ssa)
|
||||||
return matroska_parse_cluster_incremental(matroska);
|
return matroska_parse_cluster_incremental(matroska);
|
||||||
pos = avio_tell(matroska->ctx->pb);
|
pos = avio_tell(matroska->ctx->pb);
|
||||||
@ -2332,11 +2411,10 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
|
|||||||
int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
|
int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
|
||||||
if (!blocks[i].non_simple)
|
if (!blocks[i].non_simple)
|
||||||
blocks[i].duration = AV_NOPTS_VALUE;
|
blocks[i].duration = AV_NOPTS_VALUE;
|
||||||
res=matroska_parse_block(matroska,
|
res = matroska_parse_block(matroska, blocks[i].bin.data,
|
||||||
blocks[i].bin.data, blocks[i].bin.size,
|
blocks[i].bin.size, blocks[i].bin.pos,
|
||||||
blocks[i].bin.pos, cluster.timecode,
|
cluster.timecode, blocks[i].duration,
|
||||||
blocks[i].duration, is_keyframe,
|
is_keyframe, pos);
|
||||||
pos);
|
|
||||||
}
|
}
|
||||||
ebml_free(matroska_cluster, &cluster);
|
ebml_free(matroska_cluster, &cluster);
|
||||||
return res;
|
return res;
|
||||||
@ -2382,7 +2460,8 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
|
|||||||
timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
|
timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
|
||||||
|
|
||||||
if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
|
if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
|
||||||
avio_seek(s->pb, st->index_entries[st->nb_index_entries-1].pos, SEEK_SET);
|
avio_seek(s->pb, st->index_entries[st->nb_index_entries - 1].pos,
|
||||||
|
SEEK_SET);
|
||||||
matroska->current_id = 0;
|
matroska->current_id = 0;
|
||||||
while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
|
while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
|
||||||
matroska_clear_queue(matroska);
|
matroska_clear_queue(matroska);
|
||||||
@ -2401,12 +2480,15 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
|
|||||||
tracks[i].audio.sub_packet_cnt = 0;
|
tracks[i].audio.sub_packet_cnt = 0;
|
||||||
tracks[i].audio.buf_timecode = AV_NOPTS_VALUE;
|
tracks[i].audio.buf_timecode = AV_NOPTS_VALUE;
|
||||||
tracks[i].end_timecode = 0;
|
tracks[i].end_timecode = 0;
|
||||||
if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE
|
if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE &&
|
||||||
&& !tracks[i].stream->discard != AVDISCARD_ALL) {
|
!tracks[i].stream->discard != AVDISCARD_ALL) {
|
||||||
index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD);
|
index_sub = av_index_search_timestamp(
|
||||||
if (index_sub >= 0
|
tracks[i].stream, st->index_entries[index].timestamp,
|
||||||
&& st->index_entries[index_sub].pos < st->index_entries[index_min].pos
|
AVSEEK_FLAG_BACKWARD);
|
||||||
&& st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale)
|
if (index_sub >= 0 &&
|
||||||
|
st->index_entries[index_sub].pos < st->index_entries[index_min].pos &&
|
||||||
|
st->index_entries[index].timestamp -
|
||||||
|
st->index_entries[index_sub].timestamp < 30000000000 / matroska->time_scale)
|
||||||
index_min = index_sub;
|
index_min = index_sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user