summaryrefslogtreecommitdiff
path: root/libavformat/matroska.c
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2006-11-20 00:31:59 +0000
committerAurelien Jacobs <aurel@gnuage.org>2006-11-20 00:31:59 +0000
commita487d231cbf75e60f7b731ba26b99d383c165abc (patch)
tree6c24b5d1d54e8edb1d26a3623f4da2695168f7ea /libavformat/matroska.c
parent363c86ce66bcf896305c0604f3b24921d7c451f7 (diff)
matroska: split real video frames so that each packet contains only one slice
Originally committed as revision 7129 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/matroska.c')
-rw-r--r--libavformat/matroska.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index b7f27ec026..7411bd9f94 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -176,6 +176,7 @@ typedef enum {
MATROSKA_TRACK_ENABLED = (1<<0),
MATROSKA_TRACK_DEFAULT = (1<<1),
MATROSKA_TRACK_LACING = (1<<2),
+ MATROSKA_TRACK_REAL_V = (1<<4),
MATROSKA_TRACK_SHIFT = (1<<16)
} MatroskaTrackFlags;
@@ -2267,6 +2268,7 @@ matroska_read_header (AVFormatContext *s,
codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) {
extradata_offset = 26;
track->codec_priv_size -= extradata_offset;
+ track->flags |= MATROSKA_TRACK_REAL_V;
}
if (codec_id == CODEC_ID_NONE) {
@@ -2348,6 +2350,12 @@ matroska_find_track_by_num (MatroskaDemuxContext *matroska,
return -1;
}
+static inline int
+rv_offset(uint8_t *data, int slice, int slices)
+{
+ return LE_32(data+8*slice+4) + 8*slices;
+}
+
static int
matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
uint64_t cluster_time)
@@ -2498,14 +2506,14 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
}
if (res == 0) {
+ int real_v = matroska->tracks[track]->flags & MATROSKA_TRACK_REAL_V;
for (n = 0; n < laces; n++) {
uint64_t timecode = AV_NOPTS_VALUE;
+ int slice, slices = 1;
- pkt = av_mallocz(sizeof(AVPacket));
- /* XXX: prevent data copy... */
- if (av_new_packet(pkt,lace_size[n]) < 0) {
- res = AVERROR_NOMEM;
- break;
+ if (real_v) {
+ slices = *data++ + 1;
+ lace_size[n]--;
}
if (cluster_time != (uint64_t)-1 && n == 0) {
if (cluster_time + block_time >= 0)
@@ -2513,8 +2521,23 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
}
/* FIXME: duration */
- memcpy(pkt->data, data, lace_size[n]);
- data += lace_size[n];
+ for (slice=0; slice<slices; slice++) {
+ int slice_size, slice_offset = 0;
+ if (real_v)
+ slice_offset = rv_offset(data, slice, slices);
+ if (slice+1 == slices)
+ slice_size = lace_size[n] - slice_offset;
+ else
+ slice_size = rv_offset(data, slice+1, slices) - slice_offset;
+ pkt = av_mallocz(sizeof(AVPacket));
+ /* XXX: prevent data copy... */
+ if (av_new_packet(pkt, slice_size) < 0) {
+ res = AVERROR_NOMEM;
+ n = laces-1;
+ break;
+ }
+ memcpy (pkt->data, data+slice_offset, slice_size);
+
if (n == 0)
pkt->flags = is_keyframe;
pkt->stream_index =
@@ -2524,6 +2547,8 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
pkt->pos= pos;
matroska_queue_packet(matroska, pkt);
+ }
+ data += lace_size[n];
}
}