mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-06-27 02:52:25 +08:00
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
This commit is contained in:
@ -176,6 +176,7 @@ typedef enum {
|
|||||||
MATROSKA_TRACK_ENABLED = (1<<0),
|
MATROSKA_TRACK_ENABLED = (1<<0),
|
||||||
MATROSKA_TRACK_DEFAULT = (1<<1),
|
MATROSKA_TRACK_DEFAULT = (1<<1),
|
||||||
MATROSKA_TRACK_LACING = (1<<2),
|
MATROSKA_TRACK_LACING = (1<<2),
|
||||||
|
MATROSKA_TRACK_REAL_V = (1<<4),
|
||||||
MATROSKA_TRACK_SHIFT = (1<<16)
|
MATROSKA_TRACK_SHIFT = (1<<16)
|
||||||
} MatroskaTrackFlags;
|
} MatroskaTrackFlags;
|
||||||
|
|
||||||
@ -2267,6 +2268,7 @@ matroska_read_header (AVFormatContext *s,
|
|||||||
codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) {
|
codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) {
|
||||||
extradata_offset = 26;
|
extradata_offset = 26;
|
||||||
track->codec_priv_size -= extradata_offset;
|
track->codec_priv_size -= extradata_offset;
|
||||||
|
track->flags |= MATROSKA_TRACK_REAL_V;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec_id == CODEC_ID_NONE) {
|
if (codec_id == CODEC_ID_NONE) {
|
||||||
@ -2348,6 +2350,12 @@ matroska_find_track_by_num (MatroskaDemuxContext *matroska,
|
|||||||
return -1;
|
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
|
static int
|
||||||
matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
|
matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
|
||||||
uint64_t cluster_time)
|
uint64_t cluster_time)
|
||||||
@ -2498,14 +2506,14 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
|
int real_v = matroska->tracks[track]->flags & MATROSKA_TRACK_REAL_V;
|
||||||
for (n = 0; n < laces; n++) {
|
for (n = 0; n < laces; n++) {
|
||||||
uint64_t timecode = AV_NOPTS_VALUE;
|
uint64_t timecode = AV_NOPTS_VALUE;
|
||||||
|
int slice, slices = 1;
|
||||||
|
|
||||||
pkt = av_mallocz(sizeof(AVPacket));
|
if (real_v) {
|
||||||
/* XXX: prevent data copy... */
|
slices = *data++ + 1;
|
||||||
if (av_new_packet(pkt,lace_size[n]) < 0) {
|
lace_size[n]--;
|
||||||
res = AVERROR_NOMEM;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (cluster_time != (uint64_t)-1 && n == 0) {
|
if (cluster_time != (uint64_t)-1 && n == 0) {
|
||||||
if (cluster_time + block_time >= 0)
|
if (cluster_time + block_time >= 0)
|
||||||
@ -2513,8 +2521,23 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
|
|||||||
}
|
}
|
||||||
/* FIXME: duration */
|
/* FIXME: duration */
|
||||||
|
|
||||||
memcpy(pkt->data, data, lace_size[n]);
|
for (slice=0; slice<slices; slice++) {
|
||||||
data += lace_size[n];
|
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)
|
if (n == 0)
|
||||||
pkt->flags = is_keyframe;
|
pkt->flags = is_keyframe;
|
||||||
pkt->stream_index =
|
pkt->stream_index =
|
||||||
@ -2524,6 +2547,8 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
|
|||||||
pkt->pos= pos;
|
pkt->pos= pos;
|
||||||
|
|
||||||
matroska_queue_packet(matroska, pkt);
|
matroska_queue_packet(matroska, pkt);
|
||||||
|
}
|
||||||
|
data += lace_size[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user