mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-24 08:12:44 +00:00
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_TRACKMAXCACHE 0x6DF8
|
||||
#define MATROSKA_ID_TRACKDEFAULTDURATION 0x23E383
|
||||
#define MATROSKA_ID_TRACKCONTENTENCODINGS 0x6D80
|
||||
#define MATROSKA_ID_TRACKCONTENTENCODING 0x6240
|
||||
|
||||
/* IDs in the trackvideo master */
|
||||
#define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3
|
||||
@ -108,6 +110,13 @@
|
||||
#define MATROSKA_ID_AUDIOBITDEPTH 0x6264
|
||||
#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 */
|
||||
#define MATROSKA_ID_POINTENTRY 0xBB
|
||||
|
||||
@ -168,6 +177,13 @@ typedef enum {
|
||||
MATROSKA_ASPECT_RATIO_MODE_FIXED = 0x2,
|
||||
} 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,
|
||||
* it's just something I use in the muxer/demuxer.
|
||||
|
@ -55,6 +55,11 @@ typedef struct Track {
|
||||
|
||||
uint64_t default_duration;
|
||||
MatroskaTrackFlags flags;
|
||||
|
||||
int encoding_scope;
|
||||
int encoding_algo;
|
||||
uint8_t *encoding_settings;
|
||||
int encoding_settings_len;
|
||||
} MatroskaTrack;
|
||||
|
||||
typedef struct MatroskaVideoTrack {
|
||||
@ -1428,6 +1433,147 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
|
||||
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:
|
||||
av_log(matroska->ctx, AV_LOG_INFO,
|
||||
"Unknown track header entry 0x%x - ignoring\n", id);
|
||||
@ -2551,14 +2697,21 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
|
||||
} else {
|
||||
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));
|
||||
/* 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);
|
||||
n = laces-1;
|
||||
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)
|
||||
pkt->flags = is_keyframe;
|
||||
|
Loading…
Reference in New Issue
Block a user