movenc: Factorize adding fragment info into a separate function
By calling this after writing the moof the first time (for calculating the moof size), we can avoid intermediate storage of tfrf_offset in MOVTrack. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
		
							parent
							
								
									0f9eb9165b
								
							
						
					
					
						commit
						2d9d6afb8d
					
				| @ -2567,6 +2567,46 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks) | ||||
| { | ||||
|     int i; | ||||
|     for (i = 0; i < mov->nb_streams; i++) { | ||||
|         MOVTrack *track = &mov->tracks[i]; | ||||
|         MOVFragmentInfo *info; | ||||
|         if ((tracks >= 0 && i != tracks) || !track->entry) | ||||
|             continue; | ||||
|         track->nb_frag_info++; | ||||
|         if (track->nb_frag_info >= track->frag_info_capacity) { | ||||
|             unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT; | ||||
|             if (av_reallocp_array(&track->frag_info, | ||||
|                                   new_capacity, | ||||
|                                   sizeof(*track->frag_info))) | ||||
|                 return AVERROR(ENOMEM); | ||||
|             track->frag_info_capacity = new_capacity; | ||||
|         } | ||||
|         info = &track->frag_info[track->nb_frag_info - 1]; | ||||
|         info->offset   = avio_tell(pb); | ||||
|         // Try to recreate the original pts for the first packet
 | ||||
|         // from the fields we have stored
 | ||||
|         info->time     = track->start_dts + track->frag_start + | ||||
|                          track->cluster[0].cts; | ||||
|         // If the pts is less than zero, we will have trimmed
 | ||||
|         // away parts of the media track using an edit list,
 | ||||
|         // and the corresponding start presentation time is zero.
 | ||||
|         if (info->time < 0) | ||||
|             info->time = 0; | ||||
|         info->duration = track->start_dts + track->track_duration - | ||||
|                          track->cluster[0].dts; | ||||
|         info->tfrf_offset = 0; | ||||
|         mov_write_tfrf_tags(pb, mov, track); | ||||
|         // If writing all tracks, we currently only add a tfra entry for
 | ||||
|         // the first track (that actually has data to be written).
 | ||||
|         if (tracks < 0) | ||||
|             break; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track) | ||||
| { | ||||
|     int64_t pos = avio_tell(pb); | ||||
| @ -2597,7 +2637,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, | ||||
|         if (mov->ism_lookahead) { | ||||
|             int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead; | ||||
| 
 | ||||
|             track->tfrf_offset = avio_tell(pb); | ||||
|             if (track->nb_frag_info > 0) { | ||||
|                 MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1]; | ||||
|                 if (!info->tfrf_offset) | ||||
|                     info->tfrf_offset = avio_tell(pb); | ||||
|             } | ||||
|             avio_wb32(pb, 8 + size); | ||||
|             ffio_wfourcc(pb, "free"); | ||||
|             for (i = 0; i < size; i++) | ||||
| @ -2640,6 +2684,10 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks) | ||||
|         return ret; | ||||
|     mov_write_moof_tag_internal(avio_buf, mov, tracks, 0); | ||||
|     moof_size = ffio_close_null_buf(avio_buf); | ||||
| 
 | ||||
|     if ((ret = mov_add_tfra_entries(pb, mov, tracks)) < 0) | ||||
|         return ret; | ||||
| 
 | ||||
|     return mov_write_moof_tag_internal(pb, mov, tracks, moof_size); | ||||
| } | ||||
| 
 | ||||
| @ -3004,36 +3052,9 @@ static int mov_flush_fragment(AVFormatContext *s) | ||||
|         } | ||||
| 
 | ||||
|         if (write_moof) { | ||||
|             MOVFragmentInfo *info; | ||||
|             avio_flush(s->pb); | ||||
|             track->nb_frag_info++; | ||||
|             if (track->nb_frag_info >= track->frag_info_capacity) { | ||||
|                 unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT; | ||||
|                 if (av_reallocp_array(&track->frag_info, | ||||
|                                       new_capacity, | ||||
|                                       sizeof(*track->frag_info))) | ||||
|                     return AVERROR(ENOMEM); | ||||
|                 track->frag_info_capacity = new_capacity; | ||||
|             } | ||||
|             info = &track->frag_info[track->nb_frag_info - 1]; | ||||
|             info->offset   = avio_tell(s->pb); | ||||
|             info->time     = track->frag_start; | ||||
|             if (track->entry) { | ||||
|                 // Try to recreate the original pts for the first packet
 | ||||
|                 // from the fields we have stored
 | ||||
|                 info->time = track->start_dts + track->frag_start + | ||||
|                              track->cluster[0].cts; | ||||
|                 // If the pts is less than zero, we will have trimmed
 | ||||
|                 // away parts of the media track using an edit list,
 | ||||
|                 // and the corresponding start presentation time is zero.
 | ||||
|                 if (info->time < 0) | ||||
|                     info->time = 0; | ||||
|             } | ||||
|             info->duration = duration; | ||||
|             mov_write_tfrf_tags(s->pb, mov, track); | ||||
| 
 | ||||
|             mov_write_moof_tag(s->pb, mov, moof_tracks); | ||||
|             info->tfrf_offset = track->tfrf_offset; | ||||
|             mov->fragments++; | ||||
| 
 | ||||
|             avio_wb32(s->pb, mdat_size + 8); | ||||
|  | ||||
| @ -120,7 +120,6 @@ typedef struct MOVTrack { | ||||
|     AVIOContext *mdat_buf; | ||||
|     int64_t     data_offset; | ||||
|     int64_t     frag_start; | ||||
|     int64_t     tfrf_offset; | ||||
| 
 | ||||
|     int         nb_frag_info; | ||||
|     MOVFragmentInfo *frag_info; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user