tor 2021-08-12 klockan 14:38 +0200 skrev Marc-Antoine Arnaud: @@ -177,6 +179,7 @@ typedef struct { int body_sid; MXFWrappingScheme wrapping; int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */ + int* channel_ordering;
Is there a maximum number of channels? If so then this should be made constant size. } MXFTrack; typedef struct MXFDescriptor { @@ -217,6 +220,15 @@ typedef struct MXFDescriptor { size_t coll_size; } MXFDescriptor; +typedef struct MXFMCASubDescriptor { + MXFMetadataSet meta; + UID uid; + UID mca_link_id; + UID mca_group_link_id; + UID mca_label_dictionnary_id; + char *language; Language doesn't seem to be used +} MXFMCASubDescriptor; +static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str) +{ + int ret; + size_t buf_size; + + if (size < 0) + return AVERROR(EINVAL); + + buf_size = size + 1; + av_free(*str); + *str = av_malloc(buf_size); av_realloc() static int mxf_parse_structural_metadata(MXFContext *mxf) { MXFPackage *material_package = NULL; @@ -2322,7 +2461,10 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) const MXFCodecUL *pix_fmt_ul = NULL; AVStream *st; AVTimecode tc; + enum AVAudioServiceType *ast; + int* channel_ordering; int flags; + int current_channel; if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n"); @@ -2681,6 +2823,185 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->internal->need_parsing = AVSTREAM_PARSE_FULL; } st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id); + + current_channel = 0; + + channel_ordering = av_mallocz_array(descriptor->channels, sizeof(int)); + + for (j = 0; j < descriptor->sub_descriptors_count; j++) { + MXFMCASubDescriptor *mca_sub_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[j], MCASubDescriptor); + if (mca_sub_descriptor == NULL) { + continue; + } + + // Soundfield group + if (IS_KLV_KEY(mca_sub_descriptor- >mca_label_dictionnary_id, mxf_soundfield_group)) { + if (IS_KLV_KEY(mca_sub_descriptor- >mca_label_dictionnary_id, mxf_soundfield_group_51)) { + st->codecpar->channel_layout = AV_CH_LAYOUT_5POINT1; + continue; + } Consider using a table lookup for this instead. + + // Audio channel + if (IS_KLV_KEY(mca_sub_descriptor- >mca_label_dictionnary_id, mxf_audio_channel)) { + if (IS_KLV_KEY(mca_sub_descriptor- >mca_label_dictionnary_id, mxf_left_audio_channel)) { + channel_ordering[current_channel] = 0; + current_channel += 1; + } Same here, except for the special case for the impaired stuff. + + // TODO support other channels + // mxf_smpte_st2067_8_mono_one_audio_channel + // mxf_smpte_st2067_8_mono_two_audio_channel + // mxf_smpte_st2067_8_left_total_audio_channel + // mxf_smpte_st2067_8_right_total_audio_channel + // mxf_smpte_st2067_8_left_surround_total_audio_channel + // mxf_smpte_st2067_8_right_surround_total_audio_channel + // mxf_smpte_st2067_8_surround_audio_channel These should be a ticket, not just a comment in the code. Or just implement them :) + } + + // set language from MCA spoken language information + // av_dict_set(&st->metadata, "language", mca_sub_descriptor->language, 0); Stray dead code. Is language not accurate perhaps? + } + + // check if the mapping is not required + bool require_reordering = false; + for (j = 0; j < descriptor->channels; ++j) { + if (channel_ordering[j] != j) { + require_reordering = true; + break; + } + } + + if (require_reordering && is_pcm(st->codecpar->codec_id)) { + current_channel = 0; + av_log(mxf->fc, AV_LOG_INFO, "MCA Audio mapping ("); + for(j = 0; j < descriptor->channels; ++j) { + for(int k = 0; k < descriptor->channels; ++k) { + if(channel_ordering[k] == current_channel) { + av_log(mxf->fc, AV_LOG_INFO, "%d -> %d", channel_ordering[k], k); + if (current_channel != descriptor- >channels - 1) + av_log(mxf->fc, AV_LOG_INFO, ", "); + current_channel += 1; + } + } + } + av_log(mxf->fc, AV_LOG_INFO, ")\n"); AV_LOG_DEBUG +static void mxf_audio_remapping(int* channel_ordering, uint8_t* data, int size, int sample_size, int channels) +{ + int sample_offset = channels * sample_size; + int number_of_samples = size / sample_offset; + uint8_t* tmp = av_malloc(sample_offset); Could avoid malloc here as well if we capped the number of channels. + uint8_t* data_ptr = data; + + for (int sample = 0; sample < number_of_samples; ++sample) { + memcpy(tmp, data_ptr, sample_offset); + + for (int channel = 0; channel < channels; ++channel) { + for (int sample_index = 0; sample_index < sample_size; ++sample_index) { + data_ptr[sample_size * channel_ordering[channel] + sample_index] = tmp[sample_size * channel + sample_index]; + } + } This looks like it would be very slow. Lots of copying. /Tomas _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".