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; |     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) | static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track) | ||||||
| { | { | ||||||
|     int64_t pos = avio_tell(pb); |     int64_t pos = avio_tell(pb); | ||||||
| @ -2597,7 +2637,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, | |||||||
|         if (mov->ism_lookahead) { |         if (mov->ism_lookahead) { | ||||||
|             int i, size = 16 + 4 + 1 + 16 * 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); |             avio_wb32(pb, 8 + size); | ||||||
|             ffio_wfourcc(pb, "free"); |             ffio_wfourcc(pb, "free"); | ||||||
|             for (i = 0; i < size; i++) |             for (i = 0; i < size; i++) | ||||||
| @ -2640,6 +2684,10 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks) | |||||||
|         return ret; |         return ret; | ||||||
|     mov_write_moof_tag_internal(avio_buf, mov, tracks, 0); |     mov_write_moof_tag_internal(avio_buf, mov, tracks, 0); | ||||||
|     moof_size = ffio_close_null_buf(avio_buf); |     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); |     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) { |         if (write_moof) { | ||||||
|             MOVFragmentInfo *info; |  | ||||||
|             avio_flush(s->pb); |             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); |             mov_write_moof_tag(s->pb, mov, moof_tracks); | ||||||
|             info->tfrf_offset = track->tfrf_offset; |  | ||||||
|             mov->fragments++; |             mov->fragments++; | ||||||
| 
 | 
 | ||||||
|             avio_wb32(s->pb, mdat_size + 8); |             avio_wb32(s->pb, mdat_size + 8); | ||||||
|  | |||||||
| @ -120,7 +120,6 @@ typedef struct MOVTrack { | |||||||
|     AVIOContext *mdat_buf; |     AVIOContext *mdat_buf; | ||||||
|     int64_t     data_offset; |     int64_t     data_offset; | ||||||
|     int64_t     frag_start; |     int64_t     frag_start; | ||||||
|     int64_t     tfrf_offset; |  | ||||||
| 
 | 
 | ||||||
|     int         nb_frag_info; |     int         nb_frag_info; | ||||||
|     MOVFragmentInfo *frag_info; |     MOVFragmentInfo *frag_info; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user