Added support for additional content encoding (compression, encryption) in general and zlib compression in particular (to be used with VobSubs).

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@11230 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
mosu 2003-10-22 17:59:28 +00:00
parent 2d0a6214d3
commit 7f54293847
1 changed files with 360 additions and 80 deletions

View File

@ -19,12 +19,17 @@ extern "C" {
#include <ebml/EbmlVersion.h>
#include <ebml/StdIOCallback.h>
#include <matroska/KaxVersion.h>
#include <matroska/KaxAttachments.h>
#include <matroska/KaxBlock.h>
#include <matroska/KaxBlockData.h>
#include <matroska/KaxChapters.h>
#include <matroska/KaxCluster.h>
#include <matroska/KaxClusterData.h>
#if LIBMATROSKA_VERSION >= 000503
#include <matroska/KaxContentEncoding.h>
#endif
#include <matroska/KaxContexts.h>
#include <matroska/KaxCues.h>
#include <matroska/KaxCuesData.h>
@ -44,6 +49,10 @@ extern "C" {
#include <stdio.h>
#include <string.h>
#ifdef HAVE_ZLIB
#include <zlib.h>
#endif
#include "../mp_msg.h"
#include "../help_mp.h"
#include "stream.h"
@ -61,10 +70,6 @@ using namespace libebml;
using namespace libmatroska;
using namespace std;
#ifndef LIBEBML_VERSION
#define LIBEBML_VERSION 000000
#endif // LIBEBML_VERSION
#if LIBEBML_VERSION < 000500
#error libebml version too old - need at least 0.5.0
#endif
@ -83,6 +88,29 @@ extern char *audio_lang;
#define MKV_SUBCOMPRESSION_NONE 0
#define MKV_SUBCOMPRESSION_ZLIB 1
#define safefree(m) { if (m != NULL) free(m); }
void *safemalloc(int bytes) {
void *dst;
dst = malloc(bytes);
if (dst == NULL) {
mp_msg(MSGT_DEMUX, MSGL_FATAL, "[mkv] Could not allocate %d bytes of "
"memory.\n", bytes);
exit(1);
}
return dst;
}
void *safememdup(const void *src, int bytes) {
void *dst;
dst = safemalloc(bytes);
memcpy(dst, src, bytes);
return dst;
}
class mpstream_io_callback: public IOCallback {
private:
stream_t *s;
@ -149,6 +177,16 @@ typedef struct mkv_track_index {
mkv_index_entry_t *entries;
} mkv_track_index_t;
typedef struct {
uint32_t order, type, scope;
uint32_t comp_algo;
unsigned char *comp_settings;
uint32_t comp_settings_len;
uint32_t enc_algo, sig_algo, sig_hash_algo;
unsigned char *enc_keyid, *sig_keyid, *signature;
uint32_t enc_keyid_len, sig_keyid_len, signature_len;
} mkv_content_encoding_t;
typedef struct mkv_track {
uint32_t tnum, xid;
@ -190,7 +228,13 @@ typedef struct mkv_track {
// Stuff for VobSubs
mkv_sh_sub_t sh_sub;
int vobsub_compression;
// Generic content encoding support.
vector<mkv_content_encoding_t> *c_encodings;
#ifdef HAVE_ZLIB
z_stream zstream;
bool zstream_initiated;
#endif
} mkv_track_t;
typedef struct mkv_demuxer {
@ -531,22 +575,22 @@ static void handle_subtitles(demuxer_t *d, KaxBlock *block, int64_t duration) {
static mkv_track_t *new_mkv_track(mkv_demuxer_t *d) {
mkv_track_t *t;
t = (mkv_track_t *)malloc(sizeof(mkv_track_t));
if (t != NULL) {
memset(t, 0, sizeof(mkv_track_t));
d->tracks = (mkv_track_t **)realloc(d->tracks, (d->num_tracks + 1) *
sizeof(mkv_track_t *));
if (d->tracks == NULL)
return NULL;
d->tracks[d->num_tracks] = t;
d->num_tracks++;
t = (mkv_track_t *)safemalloc(sizeof(mkv_track_t));
memset(t, 0, sizeof(mkv_track_t));
d->tracks = (mkv_track_t **)realloc(d->tracks, (d->num_tracks + 1) *
sizeof(mkv_track_t *));
if (d->tracks == NULL)
return NULL;
d->tracks[d->num_tracks] = t;
d->num_tracks++;
// Set default values.
t->default_track = 1;
t->a_sfreq = 8000.0;
t->a_channels = 1;
t->language = strdup("eng");
}
// Set default values.
t->default_track = 1;
t->a_sfreq = 8000.0;
t->a_channels = 1;
t->language = strdup("eng");
t->c_encodings = new vector<mkv_content_encoding_t>;
return t;
}
@ -657,17 +701,132 @@ static bool mkv_parse_idx(mkv_track_t *t) {
return (things_found == 3);
}
static bool reverse_encodings(mkv_track_t *track, unsigned char *&data,
uint32_t &size, uint32_t type) {
int new_size;
unsigned char *new_data, *old_data;
bool modified;
vector<mkv_content_encoding_t>::iterator ce;
if (track->c_encodings->size() == 0)
return false;
new_data = data;
new_size = size;
modified = false;
for (ce = track->c_encodings->begin(); ce < track->c_encodings->end();
ce++) {
if ((ce->scope & type) == 0)
continue;
#ifdef HAVE_ZLIB
if (ce->comp_algo == 0) {
int result;
old_data = new_data;
new_data = (unsigned char *)safemalloc(new_size * 20);
track->zstream.next_in = (Bytef *)old_data;
track->zstream.next_out = (Bytef *)new_data;
track->zstream.avail_in = new_size;
track->zstream.avail_out = 20 * new_size;
result = inflate(&track->zstream, Z_FULL_FLUSH);
if (result != Z_OK) {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Zlib decompression failed. "
"Result: %d\n", result);
safefree(new_data);
data = old_data;
size = new_size;
return modified;
}
mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] zlib decompression: from %d to "
"%d\n", new_size, 20 * new_size - track->zstream.avail_out);
new_size = 20 * new_size - track->zstream.avail_out;
if (modified)
safefree(old_data);
modified = true;
}
#endif
}
data = new_data;
size = new_size;
return modified;
}
static int check_track_information(mkv_demuxer_t *d) {
int i, track_num;
unsigned char *c;
uint32_t u, offset, length;
mkv_track_t *t;
mkv_content_encoding_t *ce;
BITMAPINFOHEADER *bih;
WAVEFORMATEX *wfe;
for (track_num = 0; track_num < d->num_tracks; track_num++) {
t = d->tracks[track_num];
t->ok = 1;
for (i = 0; i < (int)t->c_encodings->size(); i++) {
ce = &(*t->c_encodings)[i];
if (ce->type == 1) {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Track number %u has been "
"encrypted and decryption has not yet been implemented. "
"Skipping track.\n", t->tnum);
t->ok = 0;
break;
}
if (ce->type != 0) {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown content encoding type %u "
"for track %u. Skipping track.\n", ce->type, t->tnum);
t->ok = 0;
break;
}
if (ce->comp_algo == 0) {
#if !defined(HAVE_ZLIB)
mp_msg(MSGT_DEMUX, MSGL_WARN, "Track %u was compressed with zlib but "
"mplayer has not been compiled with support for zlib "
"compression. Skipping track.\n", t->tnum);
t->ok = 0;
break;
#else
if (!t->zstream_initiated) {
t->zstream.zalloc = (alloc_func)0;
t->zstream.zfree = (free_func)0;
t->zstream.opaque = (voidpf)0;
inflateInit(&t->zstream);
t->zstream_initiated = true;
}
#endif
} else {
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Track %u has been compressed "
"with an unknown/unsupported compression algorithm (%u). "
"Skipping track.\n", t->tnum, ce->comp_algo);
t->ok = 0;
break;
}
}
if (!t->ok)
continue;
t->ok = 0;
if (t->private_data != NULL) {
c = (unsigned char *)t->private_data;
length = t->private_size;
if (reverse_encodings(t, c, length, 2)) {
safefree(t->private_data);
t->private_data = c;
t->private_size = length;
}
}
switch (t->type) {
case 'v': // video track
if (t->codec_id == NULL)
@ -888,7 +1047,7 @@ static int check_track_information(mkv_demuxer_t *d) {
break;
case 's':
if (!strncmp(t->codec_id, MKV_S_VOBSUB, strlen(MKV_S_VOBSUB))) {
if (!strcmp(t->codec_id, MKV_S_VOBSUB)) {
if (mkv_parse_idx(t)) {
t->ok = 1;
mp_msg(MSGT_DEMUX, MSGL_INFO, "[mkv] Track ID %u: subtitles (%s), "
@ -920,7 +1079,7 @@ static int check_track_information(mkv_demuxer_t *d) {
}
static void free_mkv_demuxer(mkv_demuxer_t *d) {
int i;
int i, k;
if (d == NULL)
return;
@ -931,6 +1090,17 @@ static void free_mkv_demuxer(mkv_demuxer_t *d) {
free(d->tracks[i]->private_data);
if (d->tracks[i]->language != NULL)
free(d->tracks[i]->language);
for (k = 0; k < (int)d->tracks[i]->c_encodings->size(); k++) {
safefree((*d->tracks[i]->c_encodings)[k].comp_settings);
safefree((*d->tracks[i]->c_encodings)[k].enc_keyid);
safefree((*d->tracks[i]->c_encodings)[k].sig_keyid);
safefree((*d->tracks[i]->c_encodings)[k].signature);
}
delete d->tracks[i]->c_encodings;
#ifdef HAVE_ZLIB
if (d->tracks[i]->zstream_initiated)
inflateEnd(&d->tracks[i]->zstream);
#endif
free(d->tracks[i]);
}
@ -1244,9 +1414,7 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
try {
// structure for storing the demuxer's private data
mkv_d = (mkv_demuxer_t *)malloc(sizeof(mkv_demuxer_t));
if (mkv_d == NULL)
return 0;
mkv_d = (mkv_demuxer_t *)safemalloc(sizeof(mkv_demuxer_t));
memset(mkv_d, 0, sizeof(mkv_demuxer_t));
mkv_d->duration = -1.0;
@ -1356,6 +1524,11 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
KaxCodecPrivate *kcodecpriv;
KaxTrackFlagDefault *ktfdefault;
KaxTrackLanguage *ktlanguage;
#if LIBMATROSKA_VERSION >= 000503
KaxContentEncodings *kcencodings;
int kcenc_idx;
vector<mkv_content_encoding_t>::iterator ce_ins_it;
#endif
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + a track...\n");
@ -1507,13 +1680,9 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + CodecPrivate, length "
"%llu\n", kcodecpriv->GetSize());
track->private_size = kcodecpriv->GetSize();
if (track->private_size > 0) {
track->private_data = malloc(track->private_size);
if (track->private_data == NULL)
return 0;
memcpy(track->private_data, kcodecpriv->GetBuffer(),
track->private_size);
}
if (track->private_size > 0)
track->private_data = safememdup(kcodecpriv->GetBuffer(),
track->private_size);
}
ktfdefault = FINDFIRST(ktentry, KaxTrackFlagDefault);
@ -1532,6 +1701,115 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
track->language = strdup(string(*ktlanguage).c_str());
}
#if LIBMATROSKA_VERSION >= 000503
kcencodings = FINDFIRST(ktentry, KaxContentEncodings);
if (kcencodings != NULL) {
for (kcenc_idx = 0; kcenc_idx < (int)kcencodings->ListSize();
kcenc_idx++) {
EbmlElement *l3;
l3 = (*kcencodings)[kcenc_idx];
if (EbmlId(*l3) == KaxContentEncoding::ClassInfos.GlobalId) {
KaxContentEncoding *kcenc;
KaxContentEncodingOrder *ce_order;
KaxContentEncodingType *ce_type;
KaxContentEncodingScope *ce_scope;
KaxContentCompression *ce_comp;
KaxContentEncryption *ce_enc;
mkv_content_encoding_t enc;
memset(&enc, 0, sizeof(mkv_content_encoding_t));
kcenc = static_cast<KaxContentEncoding *>(l3);
ce_order = FINDFIRST(kcenc, KaxContentEncodingOrder);
if (ce_order != NULL)
enc.order = uint32(*ce_order);
ce_type = FINDFIRST(kcenc, KaxContentEncodingType);
if (ce_type != NULL)
enc.type = uint32(*ce_type);
ce_scope = FINDFIRST(kcenc, KaxContentEncodingScope);
if (ce_scope != NULL)
enc.scope = uint32(*ce_scope);
else
enc.scope = 1;
ce_comp = FINDFIRST(kcenc, KaxContentCompression);
if (ce_comp != NULL) {
KaxContentCompAlgo *cc_algo;
KaxContentCompSettings *cc_settings;
cc_algo = FINDFIRST(ce_comp, KaxContentCompAlgo);
if (cc_algo != NULL)
enc.comp_algo = uint32(*cc_algo);
cc_settings = FINDFIRST(ce_comp, KaxContentCompSettings);
if (cc_settings != NULL) {
enc.comp_settings =
(unsigned char *)safememdup(&binary(*cc_settings),
cc_settings->GetSize());
enc.comp_settings_len = cc_settings->GetSize();
}
}
ce_enc = FINDFIRST(kcenc, KaxContentEncryption);
if (ce_enc != NULL) {
KaxContentEncAlgo *ce_ealgo;
KaxContentEncKeyID *ce_ekeyid;
KaxContentSigAlgo *ce_salgo;
KaxContentSigHashAlgo *ce_shalgo;
KaxContentSigKeyID *ce_skeyid;
KaxContentSignature *ce_signature;
ce_ealgo = FINDFIRST(ce_enc, KaxContentEncAlgo);
if (ce_ealgo != NULL)
enc.enc_algo = uint32(*ce_ealgo);
ce_ekeyid = FINDFIRST(ce_enc, KaxContentEncKeyID);
if (ce_ekeyid != NULL) {
enc.enc_keyid =
(unsigned char *)safememdup(&binary(*ce_ekeyid),
ce_ekeyid->GetSize());
enc.enc_keyid_len = ce_ekeyid->GetSize();
}
ce_salgo = FINDFIRST(ce_enc, KaxContentSigAlgo);
if (ce_salgo != NULL)
enc.enc_algo = uint32(*ce_salgo);
ce_shalgo = FINDFIRST(ce_enc, KaxContentSigHashAlgo);
if (ce_shalgo != NULL)
enc.enc_algo = uint32(*ce_shalgo);
ce_skeyid = FINDFIRST(ce_enc, KaxContentSigKeyID);
if (ce_skeyid != NULL) {
enc.sig_keyid =
(unsigned char *)safememdup(&binary(*ce_skeyid),
ce_skeyid->GetSize());
enc.sig_keyid_len = ce_skeyid->GetSize();
}
ce_signature = FINDFIRST(ce_enc, KaxContentSignature);
if (ce_signature != NULL) {
enc.signature =
(unsigned char *)safememdup(&binary(*ce_signature),
ce_signature->GetSize());
enc.signature_len = ce_signature->GetSize();
}
}
ce_ins_it = track->c_encodings->begin();
while ((ce_ins_it != track->c_encodings->end()) &&
(enc.order <= (*ce_ins_it).order))
ce_ins_it++;
track->c_encodings->insert(ce_ins_it, enc);
}
}
}
#endif
ktentry = FINDNEXT(l1, KaxTrackEntry, ktentry);
} // while (ktentry != NULL)
@ -1650,11 +1928,8 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
BITMAPINFOHEADER *bih;
idesc = NULL;
bih = (BITMAPINFOHEADER *)calloc(1, track->private_size);
if (bih == NULL) {
free_mkv_demuxer(mkv_d);
return 0;
}
bih = (BITMAPINFOHEADER *)safemalloc(track->private_size);
memset(bih, 0, sizeof(BITMAPINFOHEADER));
if (track->ms_compat) { // MS compatibility mode
BITMAPINFOHEADER *src;
@ -1816,19 +2091,12 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
mkv_d->audio = track;
if (track->ms_compat) {
sh_a->wf = (WAVEFORMATEX *)calloc(1, track->private_size);
if (sh_a->wf == NULL) {
free_mkv_demuxer(mkv_d);
return 0;
}
memcpy(sh_a->wf, track->private_data, track->private_size);
} else {
sh_a->wf = (WAVEFORMATEX *)calloc(1, sizeof(WAVEFORMATEX));
if (sh_a->wf == NULL) {
free_mkv_demuxer(mkv_d);
return 0;
}
if (track->ms_compat)
sh_a->wf = (WAVEFORMATEX *)safememdup(track->private_data,
track->private_size);
else {
sh_a->wf = (WAVEFORMATEX *)safemalloc(sizeof(WAVEFORMATEX));
memset(sh_a->wf, 0, sizeof(WAVEFORMATEX));
}
sh_a->format = track->a_formattag;
sh_a->wf->wFormatTag = track->a_formattag;
@ -1866,8 +2134,8 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
track->fix_i_bps = true;
track->qt_last_a_pts = 0.0;
if (track->private_data != NULL) {
sh_a->codecdata = (unsigned char *)calloc(track->private_size, 1);
memcpy(sh_a->codecdata, track->private_data, track->private_size);
sh_a->codecdata = (unsigned char *)safememdup(track->private_data,
track->private_size);
sh_a->codecdata_len = track->private_size;
}
if (!strcmp(track->codec_id, MKV_A_QDMC))
@ -1919,7 +2187,7 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
else
srate_idx = 11;
sh_a->codecdata = (unsigned char *)calloc(1, 2);
sh_a->codecdata = (unsigned char *)safemalloc(2);
sh_a->codecdata_len = 2;
sh_a->codecdata[0] = ((profile + 1) << 3) | ((srate_idx & 0xe) >> 1);
sh_a->codecdata[1] = ((srate_idx & 0x1) << 7) | (track->a_channels << 3);
@ -1988,14 +2256,14 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
else if (dvdsub_lang != NULL)
track = find_track_by_language(mkv_d, dvdsub_lang, NULL);
if (track) {
if (!strncmp(track->codec_id, MKV_S_VOBSUB, strlen(MKV_S_VOBSUB))) {
if (!strcmp(track->codec_id, MKV_S_VOBSUB)) {
mp_msg(MSGT_DEMUX, MSGL_INFO, "[mkv] Will display subtitle track %u\n",
track->tnum);
mkv_d->subs_track = track;
mkv_d->subtitle_type = MKV_SUBTYPE_VOBSUB;
demuxer->sub->sh = (mkv_sh_sub_t *)malloc(sizeof(mkv_sh_sub_t));
demuxer->sub->sh = (mkv_sh_sub_t *)safememdup(&track->sh_sub,
sizeof(mkv_sh_sub_t));
demuxer->sub->id = track->xid;
memcpy(demuxer->sub->sh, &track->sh_sub, sizeof(mkv_sh_sub_t));
} else if (strcmp(track->codec_id, MKV_S_TEXTASCII) &&
strcmp(track->codec_id, MKV_S_TEXTUTF8) &&
@ -2009,7 +2277,7 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
mkv_d->subs_track = track;
if (!mkv_d->subs.text[0]) {
for (i = 0; i < SUB_MAX_TEXT; i++)
mkv_d->subs.text[i] = (char *)malloc(256);
mkv_d->subs.text[i] = (char *)safemalloc(256);
if (!strcmp(track->codec_id, MKV_S_TEXTUTF8))
sub_utf8 = 1; // Force UTF-8 conversion.
@ -2095,9 +2363,8 @@ static float real_fix_timestamp(mkv_track_t *track, unsigned char *s,
return v_pts;
}
static void handle_realvideo(demuxer_t *demuxer, DataBuffer &data,
bool keyframe, int &found_data) {
unsigned char *p;
static void handle_realvideo(demuxer_t *demuxer, unsigned char *data,
uint32_t size, bool keyframe, int &found_data) {
dp_hdr_t *hdr;
int chunks, isize;
mkv_demuxer_t *mkv_d;
@ -2106,12 +2373,11 @@ static void handle_realvideo(demuxer_t *demuxer, DataBuffer &data,
mkv_d = (mkv_demuxer_t *)demuxer->priv;
ds = demuxer->video;
p = (unsigned char *)data.Buffer();
chunks = p[0];
isize = data.Size() - 1 - (chunks + 1) * 8;
chunks = data[0];
isize = size - 1 - (chunks + 1) * 8;
dp = new_demux_packet(sizeof(dp_hdr_t) + isize + 8 * (chunks + 1));
memcpy(&dp->buffer[sizeof(dp_hdr_t)], &p[1 + (chunks + 1) * 8], isize);
memcpy(&dp->buffer[sizeof(dp_hdr_t) + isize], &p[1], (chunks + 1) * 8);
memcpy(&dp->buffer[sizeof(dp_hdr_t)], &data[1 + (chunks + 1) * 8], isize);
memcpy(&dp->buffer[sizeof(dp_hdr_t) + isize], &data[1], (chunks + 1) * 8);
hdr = (dp_hdr_t *)dp->buffer;
hdr->len = isize;
hdr->chunks = chunks;
@ -2134,15 +2400,15 @@ static void handle_realvideo(demuxer_t *demuxer, DataBuffer &data,
found_data++;
}
static void handle_realaudio(demuxer_t *demuxer, DataBuffer &data,
bool keyframe, int &found_data) {
static void handle_realaudio(demuxer_t *demuxer, unsigned char *data,
uint32_t size, bool keyframe, int &found_data) {
mkv_demuxer_t *mkv_d;
demux_packet_t *dp;
mkv_d = (mkv_demuxer_t *)demuxer->priv;
dp = new_demux_packet(data.Size());
memcpy(dp->buffer, data.Buffer(), data.Size());
dp = new_demux_packet(size);
memcpy(dp->buffer, data, size);
if ((mkv_d->audio->ra_pts == mkv_d->last_pts) &&
!mkv_d->a_skip_to_keyframe)
dp->pts = 0;
@ -2370,6 +2636,7 @@ extern "C" int demux_mkv_fill_buffer(demuxer_t *d) {
demux_packet_t *dp;
demux_stream_t *ds;
mkv_demuxer_t *mkv_d;
mkv_track_t *t;
int upper_lvl_el, exit_loop, found_data, i, linei, sl;
char *texttmp;
// Elements for different levels
@ -2490,14 +2757,18 @@ extern "C" int demux_mkv_fill_buffer(demuxer_t *d) {
ds = NULL;
if ((mkv_d->video != NULL) &&
(mkv_d->video->tnum == kblock->TrackNum()))
(mkv_d->video->tnum == kblock->TrackNum())) {
ds = d->video;
else if ((mkv_d->audio != NULL) &&
(mkv_d->audio->tnum == kblock->TrackNum()))
t = mkv_d->video;
} else if ((mkv_d->audio != NULL) &&
(mkv_d->audio->tnum == kblock->TrackNum())) {
ds = d->audio;
else if ((mkv_d->subs_track != NULL) &&
(mkv_d->subs_track->tnum == kblock->TrackNum()))
t = mkv_d->audio;
} else if ((mkv_d->subs_track != NULL) &&
(mkv_d->subs_track->tnum == kblock->TrackNum())) {
ds = d->sub;
t = mkv_d->subs_track;
}
use_this_block = true;
@ -2564,28 +2835,37 @@ extern "C" int demux_mkv_fill_buffer(demuxer_t *d) {
mkv_d->last_filepos = d->filepos;
for (i = 0; i < (int)kblock->NumberFrames(); i++) {
unsigned char *re_buffer;
uint32_t re_size;
bool re_modified;
DataBuffer &data = kblock->GetBuffer(i);
re_buffer = data.Buffer();
re_size = data.Size();
re_modified = reverse_encodings(t, re_buffer, re_size, 1);
if ((ds == d->video) && mkv_d->video->realmedia)
handle_realvideo(d, data, block_bref == 0,
handle_realvideo(d, re_buffer, re_size, block_bref == 0,
found_data);
else if ((ds == d->audio) && mkv_d->audio->realmedia)
handle_realaudio(d, data, block_bref == 0,
handle_realaudio(d, re_buffer, re_size, block_bref == 0,
found_data);
else if ((ds == d->sub) &&
(mkv_d->subtitle_type == MKV_SUBTYPE_VOBSUB))
mpeg_run(d, (unsigned char *)data.Buffer(), data.Size());
mpeg_run(d, re_buffer, re_size);
else {
dp = new_demux_packet(data.Size());
memcpy(dp->buffer, data.Buffer(), data.Size());
dp = new_demux_packet(re_size);
memcpy(dp->buffer, re_buffer, re_size);
dp->flags = block_bref == 0 ? 1 : 0;
dp->pts = mkv_d->last_pts;
ds_add_packet(ds, dp);
found_data++;
}
if (re_modified)
safefree(re_buffer);
}
if (ds == d->video) {
mkv_d->v_skip_to_keyframe = false;