mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
write frames and syncpoints
Originally committed as revision 10032 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
491216c672
commit
e1249ba92f
@ -375,8 +375,120 @@ static int write_header(AVFormatContext *s){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_needed_flags(NUTContext *nut, StreamContext *nus, FrameCode *fc, AVPacket *pkt){
|
||||
int flags= 0;
|
||||
|
||||
if(pkt->flags & PKT_FLAG_KEY ) flags |= FLAG_KEY;
|
||||
if(pkt->stream_index != fc->stream_id ) flags |= FLAG_STREAM_ID;
|
||||
if(pkt->size / fc->size_mul ) flags |= FLAG_SIZE_MSB;
|
||||
if(pkt->pts - nus->last_pts != fc->pts_delta) flags |= FLAG_CODED_PTS;
|
||||
if(pkt->size > 2*nut->max_distance ) flags |= FLAG_CHECKSUM;
|
||||
if(FFABS(pkt->pts - nus->last_pts)
|
||||
> nus->max_pts_distance) flags |= FLAG_CHECKSUM;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int write_packet(AVFormatContext *s, AVPacket *pkt){
|
||||
//FIXME
|
||||
NUTContext *nut = s->priv_data;
|
||||
StreamContext *nus= &nut->stream[pkt->stream_index];
|
||||
ByteIOContext *bc = &s->pb, dyn_bc;
|
||||
FrameCode *fc;
|
||||
int64_t coded_pts;
|
||||
int best_length, frame_code, flags, needed_flags, i;
|
||||
int key_frame = !!(pkt->flags & PKT_FLAG_KEY);
|
||||
int store_sp=0;
|
||||
|
||||
if(key_frame && !!(nus->last_flags & FLAG_KEY))
|
||||
store_sp= 1;
|
||||
|
||||
if(pkt->size + 30/*FIXME check*/ + url_ftell(bc) >= nut->last_syncpoint_pos + nut->max_distance)
|
||||
store_sp= 1;
|
||||
|
||||
//FIXME ensure store_sp is 1 for the first thing
|
||||
|
||||
if(store_sp){
|
||||
ff_nut_reset_ts(nut, *nus->time_base, pkt->dts);
|
||||
|
||||
nut->last_syncpoint_pos= url_ftell(bc);
|
||||
put_be64(bc, SYNCPOINT_STARTCODE);
|
||||
url_open_dyn_buf(&dyn_bc);
|
||||
put_t(nut, nus, &dyn_bc, pkt->dts);
|
||||
put_v(&dyn_bc, 0); //FIXME back_ptr_div16
|
||||
put_packet(nut, bc, &dyn_bc, 1);
|
||||
}
|
||||
assert(nus->last_pts != AV_NOPTS_VALUE);
|
||||
|
||||
coded_pts = pkt->pts & ((1<<nus->msb_pts_shift)-1);
|
||||
if(ff_lsb2full(nus, coded_pts) != pkt->pts)
|
||||
coded_pts= pkt->pts + (1<<nus->msb_pts_shift);
|
||||
|
||||
best_length=INT_MAX;
|
||||
frame_code= -1;
|
||||
for(i=0; i<256; i++){
|
||||
int length= 0;
|
||||
FrameCode *fc= &nut->frame_code[i];
|
||||
int flags= fc->flags;
|
||||
|
||||
if(flags & FLAG_INVALID)
|
||||
continue;
|
||||
needed_flags= get_needed_flags(nut, nus, fc, pkt);
|
||||
|
||||
if(flags & FLAG_CODED){
|
||||
length++;
|
||||
flags &= ~needed_flags;
|
||||
flags |= needed_flags;
|
||||
}
|
||||
|
||||
if((flags & needed_flags) != needed_flags)
|
||||
continue;
|
||||
|
||||
if((flags ^ needed_flags) & FLAG_KEY)
|
||||
continue;
|
||||
|
||||
if(flags & FLAG_STREAM_ID)
|
||||
length+= get_length(pkt->stream_index);
|
||||
|
||||
if(pkt->size % fc->size_mul != fc->size_lsb)
|
||||
continue;
|
||||
if(flags & FLAG_SIZE_MSB)
|
||||
length += get_length(pkt->size / fc->size_mul);
|
||||
|
||||
if(flags & FLAG_CHECKSUM)
|
||||
length+=4;
|
||||
|
||||
if(flags & FLAG_CODED_PTS)
|
||||
length += get_length(coded_pts);
|
||||
|
||||
length*=4;
|
||||
length+= !(flags & FLAG_CODED_PTS);
|
||||
length+= !(flags & FLAG_CHECKSUM);
|
||||
|
||||
if(length < best_length){
|
||||
best_length= length;
|
||||
frame_code=i;
|
||||
}
|
||||
}
|
||||
assert(frame_code != -1);
|
||||
fc= &nut->frame_code[frame_code];
|
||||
flags= fc->flags;
|
||||
needed_flags= get_needed_flags(nut, nus, fc, pkt);
|
||||
|
||||
init_checksum(bc, av_crc04C11DB7_update, 0);
|
||||
put_byte(bc, frame_code);
|
||||
if(flags & FLAG_CODED){
|
||||
put_v(bc, (flags^needed_flags) & ~(FLAG_CODED));
|
||||
flags = needed_flags;
|
||||
}
|
||||
if(flags & FLAG_STREAM_ID) put_v(bc, pkt->stream_index);
|
||||
if(flags & FLAG_CODED_PTS) put_v(bc, coded_pts);
|
||||
if(flags & FLAG_SIZE_MSB) put_v(bc, pkt->size / fc->size_mul);
|
||||
|
||||
if(flags & FLAG_CHECKSUM) put_le32(bc, get_checksum(bc));
|
||||
else get_checksum(bc);
|
||||
|
||||
put_buffer(bc, pkt->data, pkt->size);
|
||||
nus->last_flags= flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user