static void dash_packager_init_mp4_calc_size( media_set_t* media_set, atom_writer_t* extra_moov_atoms_writer, atom_writer_t* stsd_atom_writer, init_mp4_sizes_t* result) { media_track_t* first_track = media_set->sequences[0].filtered_clips[0].first_track; if (stsd_atom_writer != NULL) { result->stsd_size = stsd_atom_writer->atom_size; } else { result->stsd_size = first_track->raw_atoms[RTA_STSD].size; } dash_packager_get_track_sizes(first_track, result->stsd_size, &result->track_sizes); result->mvex_atom_size = ATOM_HEADER_SIZE + ATOM_HEADER_SIZE + sizeof(trex_atom_t); result->moov_atom_size = ATOM_HEADER_SIZE + result->track_sizes.track_trak_size + result->mvex_atom_size; if (media_set->sequences[0].filtered_clips[0].mvhd_atom.ptr != NULL) { result->moov_atom_size += media_set->sequences[0].filtered_clips[0].mvhd_atom.size; } else if (media_set->total_duration > UINT_MAX) { result->moov_atom_size += ATOM_HEADER_SIZE + sizeof(mvhd64_atom_t); } else { result->moov_atom_size += ATOM_HEADER_SIZE + sizeof(mvhd_atom_t); } if (extra_moov_atoms_writer != NULL) { result->moov_atom_size += extra_moov_atoms_writer->atom_size; } result->total_size = sizeof(ftyp_atom) + result->moov_atom_size; }
vod_status_t dash_packager_build_init_mp4( request_context_t* request_context, mpeg_metadata_t* mpeg_metadata, bool_t size_only, atom_writer_t* extra_moov_atoms_writer, atom_writer_t* stsd_atom_writer, vod_str_t* result) { track_sizes_t track_sizes; size_t moov_atom_size; size_t mvex_atom_size; size_t result_size; size_t stsd_size; u_char* p; // calc moov atom size if (stsd_atom_writer != NULL) { stsd_size = stsd_atom_writer->atom_size; } else { stsd_size = mpeg_metadata->first_stream->raw_atoms[RTA_STSD].size; } dash_packager_get_track_sizes(mpeg_metadata->first_stream, stsd_size, &track_sizes); mvex_atom_size = ATOM_HEADER_SIZE + ATOM_HEADER_SIZE + sizeof(trex_atom_t); moov_atom_size = ATOM_HEADER_SIZE + mpeg_metadata->mvhd_atom.size + track_sizes.track_trak_size + mvex_atom_size; if (extra_moov_atoms_writer != NULL) { moov_atom_size += extra_moov_atoms_writer->atom_size; } result_size = sizeof(ftyp_atom) + moov_atom_size; // head request optimization if (size_only) { result->len = result_size; return VOD_OK; } // allocate the buffer result->data = vod_alloc(request_context->pool, result_size); if (result->data == NULL) { vod_log_debug0(VOD_LOG_DEBUG_LEVEL, request_context->log, 0, "dash_packager_build_init_mp4: vod_alloc failed"); return VOD_ALLOC_FAILED; } // ftyp p = vod_copy(result->data, ftyp_atom, sizeof(ftyp_atom)); // moov write_atom_header(p, moov_atom_size, 'm', 'o', 'o', 'v'); // moov.mvhd p = vod_copy_atom(p, mpeg_metadata->mvhd_atom); // moov.mvex write_atom_header(p, mvex_atom_size, 'm', 'v', 'e', 'x'); // moov.mvex.trex p = dash_packager_write_trex_atom(p, mpeg_metadata->first_stream->media_info.track_id); // moov.trak write_atom_header(p, track_sizes.track_trak_size, 't', 'r', 'a', 'k'); p = vod_copy_atom(p, mpeg_metadata->first_stream->raw_atoms[RTA_TKHD]); // moov.trak.mdia write_atom_header(p, track_sizes.track_mdia_size, 'm', 'd', 'i', 'a'); p = vod_copy_atom(p, mpeg_metadata->first_stream->raw_atoms[RTA_MDHD]); p = vod_copy_atom(p, mpeg_metadata->first_stream->raw_atoms[RTA_HDLR]); // moov.trak.minf write_atom_header(p, track_sizes.track_minf_size, 'm', 'i', 'n', 'f'); switch (mpeg_metadata->first_stream->media_info.media_type) { case MEDIA_TYPE_VIDEO: p = vod_copy(p, vmhd_atom, sizeof(vmhd_atom)); break; case MEDIA_TYPE_AUDIO: p = vod_copy(p, smhd_atom, sizeof(smhd_atom)); break; } p = vod_copy_atom(p, mpeg_metadata->first_stream->raw_atoms[RTA_DINF]); // moov.trak.minf.stbl write_atom_header(p, track_sizes.track_stbl_size, 's', 't', 'b', 'l'); if (stsd_atom_writer != NULL) { p = stsd_atom_writer->write(stsd_atom_writer->context, p); } else { p = vod_copy_atom(p, mpeg_metadata->first_stream->raw_atoms[RTA_STSD]); } p = vod_copy(p, fixed_stbl_atoms, sizeof(fixed_stbl_atoms)); // moov.xxx if (extra_moov_atoms_writer != NULL) { p = extra_moov_atoms_writer->write(extra_moov_atoms_writer->context, p); } result->len = p - result->data; if (result->len != result_size) { vod_log_error(VOD_LOG_ERR, request_context->log, 0, "dash_packager_build_init_mp4: result length %uz different than allocated length %uz", result->len, result_size); return VOD_UNEXPECTED; } return VOD_OK; }