diff options
author | Aurelien Jacobs <aurel@gnuage.org> | 2006-11-20 00:31:59 +0000 |
---|---|---|
committer | Aurelien Jacobs <aurel@gnuage.org> | 2006-11-20 00:31:59 +0000 |
commit | a487d231cbf75e60f7b731ba26b99d383c165abc (patch) | |
tree | 6c24b5d1d54e8edb1d26a3623f4da2695168f7ea /libavformat/matroska.c | |
parent | 363c86ce66bcf896305c0604f3b24921d7c451f7 (diff) | |
download | ffmpeg-streaming-a487d231cbf75e60f7b731ba26b99d383c165abc.zip ffmpeg-streaming-a487d231cbf75e60f7b731ba26b99d383c165abc.tar.gz |
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.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/libavformat/matroska.c b/libavformat/matroska.c index b7f27ec..7411bd9 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]; } } |