mirror of https://git.ffmpeg.org/ffmpeg.git
matroskadec: add support for track content encoding
Only the header strip method is supported for now. Originally committed as revision 13082 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
40d0e665d0
commit
53a1e82bd2
|
@ -89,6 +89,8 @@
|
||||||
#define MATROSKA_ID_TRACKMINCACHE 0x6DE7
|
#define MATROSKA_ID_TRACKMINCACHE 0x6DE7
|
||||||
#define MATROSKA_ID_TRACKMAXCACHE 0x6DF8
|
#define MATROSKA_ID_TRACKMAXCACHE 0x6DF8
|
||||||
#define MATROSKA_ID_TRACKDEFAULTDURATION 0x23E383
|
#define MATROSKA_ID_TRACKDEFAULTDURATION 0x23E383
|
||||||
|
#define MATROSKA_ID_TRACKCONTENTENCODINGS 0x6D80
|
||||||
|
#define MATROSKA_ID_TRACKCONTENTENCODING 0x6240
|
||||||
|
|
||||||
/* IDs in the trackvideo master */
|
/* IDs in the trackvideo master */
|
||||||
#define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3
|
#define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3
|
||||||
|
@ -108,6 +110,13 @@
|
||||||
#define MATROSKA_ID_AUDIOBITDEPTH 0x6264
|
#define MATROSKA_ID_AUDIOBITDEPTH 0x6264
|
||||||
#define MATROSKA_ID_AUDIOCHANNELS 0x9F
|
#define MATROSKA_ID_AUDIOCHANNELS 0x9F
|
||||||
|
|
||||||
|
/* IDs in the content encoding master */
|
||||||
|
#define MATROSKA_ID_ENCODINGSCOPE 0x5032
|
||||||
|
#define MATROSKA_ID_ENCODINGTYPE 0x5033
|
||||||
|
#define MATROSKA_ID_ENCODINGCOMPRESSION 0x5034
|
||||||
|
#define MATROSKA_ID_ENCODINGCOMPALGO 0x4254
|
||||||
|
#define MATROSKA_ID_ENCODINGCOMPSETTINGS 0x4255
|
||||||
|
|
||||||
/* ID in the cues master */
|
/* ID in the cues master */
|
||||||
#define MATROSKA_ID_POINTENTRY 0xBB
|
#define MATROSKA_ID_POINTENTRY 0xBB
|
||||||
|
|
||||||
|
@ -168,6 +177,13 @@ typedef enum {
|
||||||
MATROSKA_ASPECT_RATIO_MODE_FIXED = 0x2,
|
MATROSKA_ASPECT_RATIO_MODE_FIXED = 0x2,
|
||||||
} MatroskaAspectRatioMode;
|
} MatroskaAspectRatioMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MATROSKA_TRACK_ENCODING_COMP_ZLIB = 0,
|
||||||
|
MATROSKA_TRACK_ENCODING_COMP_BZLIB = 1,
|
||||||
|
MATROSKA_TRACK_ENCODING_COMP_LZO = 2,
|
||||||
|
MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP = 3,
|
||||||
|
} MatroskaTrackEncodingCompAlgo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These aren't in any way "matroska-form" things,
|
* These aren't in any way "matroska-form" things,
|
||||||
* it's just something I use in the muxer/demuxer.
|
* it's just something I use in the muxer/demuxer.
|
||||||
|
|
|
@ -55,6 +55,11 @@ typedef struct Track {
|
||||||
|
|
||||||
uint64_t default_duration;
|
uint64_t default_duration;
|
||||||
MatroskaTrackFlags flags;
|
MatroskaTrackFlags flags;
|
||||||
|
|
||||||
|
int encoding_scope;
|
||||||
|
int encoding_algo;
|
||||||
|
uint8_t *encoding_settings;
|
||||||
|
int encoding_settings_len;
|
||||||
} MatroskaTrack;
|
} MatroskaTrack;
|
||||||
|
|
||||||
typedef struct MatroskaVideoTrack {
|
typedef struct MatroskaVideoTrack {
|
||||||
|
@ -1428,6 +1433,147 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MATROSKA_ID_TRACKCONTENTENCODINGS: {
|
||||||
|
if ((res = ebml_read_master(matroska, &id)) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
while (res == 0) {
|
||||||
|
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
|
||||||
|
res = AVERROR(EIO);
|
||||||
|
break;
|
||||||
|
} else if (matroska->level_up > 0) {
|
||||||
|
matroska->level_up--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case MATROSKA_ID_TRACKCONTENTENCODING: {
|
||||||
|
int encoding_scope = 1;
|
||||||
|
if ((res = ebml_read_master(matroska, &id)) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
while (res == 0) {
|
||||||
|
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
|
||||||
|
res = AVERROR(EIO);
|
||||||
|
break;
|
||||||
|
} else if (matroska->level_up > 0) {
|
||||||
|
matroska->level_up--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case MATROSKA_ID_ENCODINGSCOPE: {
|
||||||
|
uint64_t num;
|
||||||
|
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
|
||||||
|
break;
|
||||||
|
encoding_scope = num;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MATROSKA_ID_ENCODINGTYPE: {
|
||||||
|
uint64_t num;
|
||||||
|
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
|
||||||
|
break;
|
||||||
|
if (num)
|
||||||
|
av_log(matroska->ctx, AV_LOG_ERROR,
|
||||||
|
"Unsupported encoding type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MATROSKA_ID_ENCODINGCOMPRESSION: {
|
||||||
|
if ((res = ebml_read_master(matroska, &id)) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
while (res == 0) {
|
||||||
|
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
|
||||||
|
res = AVERROR(EIO);
|
||||||
|
break;
|
||||||
|
} else if (matroska->level_up > 0) {
|
||||||
|
matroska->level_up--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case MATROSKA_ID_ENCODINGCOMPALGO: {
|
||||||
|
uint64_t num;
|
||||||
|
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
|
||||||
|
break;
|
||||||
|
if (num != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP)
|
||||||
|
av_log(matroska->ctx, AV_LOG_ERROR,
|
||||||
|
"Unsupported compression algo");
|
||||||
|
track->encoding_algo = num;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MATROSKA_ID_ENCODINGCOMPSETTINGS: {
|
||||||
|
uint8_t *data;
|
||||||
|
int size;
|
||||||
|
if ((res = ebml_read_binary(matroska, &id, &data, &size) < 0))
|
||||||
|
break;
|
||||||
|
track->encoding_settings = data;
|
||||||
|
track->encoding_settings_len = size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
av_log(matroska->ctx, AV_LOG_INFO,
|
||||||
|
"Unknown compression header entry "
|
||||||
|
"0x%x - ignoring\n", id);
|
||||||
|
/* pass-through */
|
||||||
|
|
||||||
|
case EBML_ID_VOID:
|
||||||
|
res = ebml_read_skip(matroska);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matroska->level_up) {
|
||||||
|
matroska->level_up--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
av_log(matroska->ctx, AV_LOG_INFO,
|
||||||
|
"Unknown content encoding header entry "
|
||||||
|
"0x%x - ignoring\n", id);
|
||||||
|
/* pass-through */
|
||||||
|
|
||||||
|
case EBML_ID_VOID:
|
||||||
|
res = ebml_read_skip(matroska);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matroska->level_up) {
|
||||||
|
matroska->level_up--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track->encoding_scope = encoding_scope;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
av_log(matroska->ctx, AV_LOG_INFO,
|
||||||
|
"Unknown content encodings header entry "
|
||||||
|
"0x%x - ignoring\n", id);
|
||||||
|
/* pass-through */
|
||||||
|
|
||||||
|
case EBML_ID_VOID:
|
||||||
|
res = ebml_read_skip(matroska);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matroska->level_up) {
|
||||||
|
matroska->level_up--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
av_log(matroska->ctx, AV_LOG_INFO,
|
av_log(matroska->ctx, AV_LOG_INFO,
|
||||||
"Unknown track header entry 0x%x - ignoring\n", id);
|
"Unknown track header entry 0x%x - ignoring\n", id);
|
||||||
|
@ -2551,14 +2697,21 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
|
||||||
} else {
|
} else {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
|
if (matroska->tracks[track]->encoding_scope&1 &&
|
||||||
|
matroska->tracks[track]->encoding_algo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) {
|
||||||
|
offset = matroska->tracks[track]->encoding_settings_len;
|
||||||
|
}
|
||||||
|
|
||||||
pkt = av_mallocz(sizeof(AVPacket));
|
pkt = av_mallocz(sizeof(AVPacket));
|
||||||
/* XXX: prevent data copy... */
|
/* XXX: prevent data copy... */
|
||||||
if (av_new_packet(pkt, lace_size[n]-offset) < 0) {
|
if (av_new_packet(pkt, lace_size[n]+offset) < 0) {
|
||||||
res = AVERROR(ENOMEM);
|
res = AVERROR(ENOMEM);
|
||||||
n = laces-1;
|
n = laces-1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memcpy (pkt->data, data+offset, lace_size[n]-offset);
|
if (offset)
|
||||||
|
memcpy (pkt->data, matroska->tracks[track]->encoding_settings, offset);
|
||||||
|
memcpy (pkt->data+offset, data, lace_size[n]);
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
pkt->flags = is_keyframe;
|
pkt->flags = is_keyframe;
|
||||||
|
|
Loading…
Reference in New Issue