mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
write 'stps' for mpeg-2 open gop in .mov
Originally committed as revision 18838 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
9d9a623925
commit
e1316b19ea
@ -51,6 +51,7 @@ typedef struct MOVIentry {
|
||||
int cts;
|
||||
int64_t dts;
|
||||
#define MOV_SYNC_SAMPLE 0x0001
|
||||
#define MOV_PARTIAL_SYNC_SAMPLE 0x0002
|
||||
uint32_t flags;
|
||||
} MOVIentry;
|
||||
|
||||
@ -63,7 +64,9 @@ typedef struct MOVIndex {
|
||||
long sampleCount;
|
||||
long sampleSize;
|
||||
int hasKeyframes;
|
||||
int hasBframes;
|
||||
#define MOV_TRACK_CTTS 0x0001
|
||||
#define MOV_TRACK_STPS 0x0002
|
||||
uint32_t flags;
|
||||
int language;
|
||||
int trackID;
|
||||
int tag; ///< stsd fourcc
|
||||
@ -188,18 +191,18 @@ static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
}
|
||||
|
||||
/* Sync sample atom */
|
||||
static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack *track, uint32_t flag)
|
||||
{
|
||||
int64_t curpos, entryPos;
|
||||
int i, index = 0;
|
||||
int64_t pos = url_ftell(pb);
|
||||
put_be32(pb, 0); // size
|
||||
put_tag(pb, "stss");
|
||||
put_tag(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
|
||||
put_be32(pb, 0); // version & flags
|
||||
entryPos = url_ftell(pb);
|
||||
put_be32(pb, track->entry); // entry count
|
||||
for (i=0; i<track->entry; i++) {
|
||||
if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
|
||||
if (track->cluster[i].flags & flag) {
|
||||
put_be32(pb, i+1);
|
||||
index++;
|
||||
}
|
||||
@ -914,9 +917,11 @@ static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack *track)
|
||||
mov_write_stts_tag(pb, track);
|
||||
if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
|
||||
track->hasKeyframes && track->hasKeyframes < track->entry)
|
||||
mov_write_stss_tag(pb, track);
|
||||
mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
|
||||
if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
|
||||
mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
|
||||
if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
|
||||
track->hasBframes)
|
||||
track->flags & MOV_TRACK_CTTS)
|
||||
mov_write_ctts_tag(pb, track);
|
||||
mov_write_stsc_tag(pb, track);
|
||||
mov_write_stsz_tag(pb, track);
|
||||
@ -1173,7 +1178,7 @@ static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
|
||||
put_be32(pb, 0); /* size */
|
||||
put_tag(pb, "trak");
|
||||
mov_write_tkhd_tag(pb, track, st);
|
||||
if (track->mode == MODE_PSP || track->hasBframes)
|
||||
if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS)
|
||||
mov_write_edts_tag(pb, track); // PSP Movies require edts box
|
||||
mov_write_mdia_tag(pb, track);
|
||||
if (track->mode == MODE_PSP)
|
||||
@ -1802,6 +1807,27 @@ static int mov_write_header(AVFormatContext *s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
|
||||
{
|
||||
uint32_t c = -1;
|
||||
int i, closed_gop = 0;
|
||||
|
||||
for (i = 0; i < pkt->size - 4; i++) {
|
||||
c = (c<<8) + pkt->data[i];
|
||||
if (c == 0x1b8) { // gop
|
||||
closed_gop = pkt->data[i+4]>>6 & 0x01;
|
||||
} else if (c == 0x100) { // pic
|
||||
int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
|
||||
if (!temp_ref || closed_gop) // I picture is not reordered
|
||||
*flags = MOV_SYNC_SAMPLE;
|
||||
else
|
||||
*flags = MOV_PARTIAL_SYNC_SAMPLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
MOVMuxContext *mov = s->priv_data;
|
||||
@ -1876,10 +1902,18 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
pkt->pts = pkt->dts;
|
||||
}
|
||||
if (pkt->dts != pkt->pts)
|
||||
trk->hasBframes = 1;
|
||||
trk->flags |= MOV_TRACK_CTTS;
|
||||
trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
|
||||
trk->cluster[trk->entry].flags = 0;
|
||||
if (pkt->flags & PKT_FLAG_KEY) {
|
||||
if (mov->mode == MODE_MOV && enc->codec_id == CODEC_ID_MPEG2VIDEO) {
|
||||
mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags);
|
||||
if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
|
||||
trk->flags |= MOV_TRACK_STPS;
|
||||
} else {
|
||||
trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
|
||||
}
|
||||
if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
|
||||
trk->hasKeyframes++;
|
||||
}
|
||||
trk->entry++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user