bool AVFormatWriter::OpenAudio(void) { AVCodecContext *c; AVCodec *codec; c = m_audioStream->codec; c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; codec = avcodec_find_encoder(c->codec_id); if (!codec) { LOG(VB_RECORD, LOG_ERR, LOC + "OpenAudio(): avcodec_find_encoder() failed"); return false; } // try to find suitable format we can use. avcodec_open2 will fail if we don't // find one, so no need to worry otherwise. Can only handle S16 or FLOAT // we give priority to S16 as libmp3lame requires aligned floats which we can't guarantee if (!FindAudioFormat(c, codec, AV_SAMPLE_FMT_S16)) { FindAudioFormat(c, codec, AV_SAMPLE_FMT_FLT); } if (avcodec_open2(c, codec, NULL) < 0) { LOG(VB_RECORD, LOG_ERR, LOC + "OpenAudio(): avcodec_open() failed"); return false; } m_audioFrameSize = c->frame_size; // number of *samples* per channel in an AVFrame m_audPicture = avcodec_alloc_frame(); if (!m_audPicture) { LOG(VB_RECORD, LOG_ERR, LOC + "OpenAudio(): alloc_frame() failed"); return false; } int samples_per_frame = m_audioFrameSize * m_audioChannels; int bps = av_get_bytes_per_sample(c->sample_fmt); if (av_get_packed_sample_fmt(c->sample_fmt) == AV_SAMPLE_FMT_FLT) { // allocate buffer to convert from S16 to float if (!(m_audioInBuf = (unsigned char*)av_malloc(bps * samples_per_frame))) return false; } if (av_sample_fmt_is_planar(c->sample_fmt)) { // allocate buffer to convert interleaved to planar audio if (!(m_audioInPBuf = (unsigned char*)av_malloc(bps * samples_per_frame))) return false; } return true; }
/** * Initialize our main context FFAudioIO, so that SwrContext, decode buffers and the encoder are set * to reasonable values. * * @param JNIEnv env * @param aio our context, FFAudioIO * @return a negative value, if something went wrong */ int ff_init_audioio(JNIEnv *env, FFAudioIO *aio) { int res = 0; int nb_planes; AVCodec *codec = NULL; aio->timestamp = 0; // allocate pointer to the audio buffers, i.e. the multiple planes/channels. nb_planes = av_sample_fmt_is_planar(aio->stream->codecpar->format) ? aio->stream->codecpar->channels : 1; // always init SWR to keep code simpler res = init_swr(env, aio); if (res < 0) { // exception is already thrown goto bail; } // if for some reason the codec delivers 24bit, we need to encode its output to little endian if (aio->stream->codecpar->bits_per_coded_sample == 24) { codec = ff_find_encoder(aio->stream->codecpar->format, aio->stream->codecpar->bits_per_coded_sample, ff_big_endian(aio->stream->codecpar->codec_id), 1); if (!codec) { res = AVERROR(EINVAL); throwIOExceptionIfError(env, res, "Could not find suitable encoder codec."); goto bail; } res = ff_init_encoder(env, aio, codec); if (res<0) { throwIOExceptionIfError(env, res, "Could not initialize encoder codec."); goto bail; } } // allocate the buffer the codec decodes to aio->audio_data = av_mallocz(sizeof(uint8_t *) * nb_planes); if (!aio->audio_data) { res = AVERROR(ENOMEM); throwIOExceptionIfError(env, res, "Could not allocate audio data buffers."); goto bail; } aio->decode_frame = av_frame_alloc(); if (!aio->decode_frame) { res = AVERROR(ENOMEM); throwIOExceptionIfError(env, res, "Could not allocate frame."); goto bail; } // initialize packet av_init_packet(&(aio->decode_packet)); aio->decode_packet.data = NULL; aio->decode_packet.size = 0; bail: return res; }
static int get_audio_buffer(AVFrame *frame, int align) { int channels; int planar = av_sample_fmt_is_planar(frame->format); int planes; int ret, i; if (!frame->channels) frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); channels = frame->channels; planes = planar ? channels : 1; CHECK_CHANNELS_CONSISTENCY(frame); if (!frame->linesize[0]) { ret = av_samples_get_buffer_size(&frame->linesize[0], channels, frame->nb_samples, frame->format, align); if (ret < 0) return ret; } if (planes > AV_NUM_DATA_POINTERS) { frame->extended_data = av_mallocz_array(planes, sizeof(*frame->extended_data)); frame->extended_buf = av_mallocz_array((planes - AV_NUM_DATA_POINTERS), sizeof(*frame->extended_buf)); if (!frame->extended_data || !frame->extended_buf) { av_freep(&frame->extended_data); av_freep(&frame->extended_buf); return AVERROR(ENOMEM); } frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; } else frame->extended_data = frame->data; for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { frame->buf[i] = av_buffer_alloc(frame->linesize[0]); if (!frame->buf[i]) { av_frame_unref(frame); return AVERROR(ENOMEM); } frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; } for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) { frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]); if (!frame->extended_buf[i]) { av_frame_unref(frame); return AVERROR(ENOMEM); } frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; } return 0; }
AVFilterFormats *ff_planar_sample_fmts(void) { AVFilterFormats *ret = NULL; int fmt; for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++) if (av_sample_fmt_is_planar(fmt)) ff_add_format(&ret, fmt); return ret; }
AVFilterFormats *ff_planar_sample_fmts(void) { AVFilterFormats *ret = NULL; int fmt; for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++) if (av_sample_fmt_is_planar(fmt)) ff_add_format(&ret, fmt); return ret; }
int alloc_samples_array_and_data(uint8_t ***data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) { int nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1; *data = av_malloc(sizeof(*data) * nb_planes); if (!*data) return AVERROR(ENOMEM); return av_samples_alloc(*data, linesize, nb_channels, nb_samples, sample_fmt, align); }
static void shift(uint8_t *a[], int index, int ch_count, enum AVSampleFormat f){ int ch; if(av_sample_fmt_is_planar(f)){ f= av_get_alt_sample_fmt(f, 0); for(ch= 0; ch<ch_count; ch++) a[ch] += index*av_get_bytes_per_sample(f); }else{ a[0] += index*ch_count*av_get_bytes_per_sample(f); } }
static void setup_array(uint8_t *out[SWR_CH_MAX], uint8_t *in, enum AVSampleFormat format, int samples){ if(av_sample_fmt_is_planar(format)){ int i; int plane_size= av_get_bytes_per_sample(format&0xFF)*samples; format&=0xFF; for(i=0; i<SWR_CH_MAX; i++){ out[i]= in + i*plane_size; } }else{ out[0]= in; } }
static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; MixContext *s = ctx->priv; int i; char buf[64]; s->planar = av_sample_fmt_is_planar(outlink->format); s->sample_rate = outlink->sample_rate; #ifdef IDE_COMPILE outlink->time_base.num = 1; outlink->time_base.den = outlink->sample_rate; #else outlink->time_base = (AVRational){ 1, outlink->sample_rate }; #endif s->next_pts = AV_NOPTS_VALUE; s->frame_list = av_mallocz(sizeof(*s->frame_list)); if (!s->frame_list) return AVERROR(ENOMEM); s->fifos = av_mallocz(s->nb_inputs * sizeof(*s->fifos)); if (!s->fifos) return AVERROR(ENOMEM); s->nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout); for (i = 0; i < s->nb_inputs; i++) { s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, 1024); if (!s->fifos[i]) return AVERROR(ENOMEM); } s->input_state = av_malloc(s->nb_inputs); if (!s->input_state) return AVERROR(ENOMEM); memset(s->input_state, INPUT_ON, s->nb_inputs); s->active_inputs = s->nb_inputs; s->input_scale = av_mallocz_array(s->nb_inputs, sizeof(*s->input_scale)); if (!s->input_scale) return AVERROR(ENOMEM); s->scale_norm = s->active_inputs; calculate_scales(s, 0); av_get_channel_layout_string(buf, sizeof(buf), -1, outlink->channel_layout); av_log(ctx, AV_LOG_VERBOSE, "inputs:%d fmt:%s srate:%d cl:%s\n", s->nb_inputs, av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf); return 0; }
int CMixer::Mixing(float* pOutput, int out_samples, BYTE* pInput, int in_samples) { int in_ch = av_popcount(m_in_layout); int out_ch = av_popcount(m_out_layout); int in_plane_nb = av_sample_fmt_is_planar(m_in_avsf) ? in_ch : 1; int in_plane_size = in_samples * (av_sample_fmt_is_planar(m_in_avsf) ? 1 : in_ch) * av_get_bytes_per_sample(m_in_avsf); static BYTE* ppInput[AVRESAMPLE_MAX_CHANNELS]; for (int i = 0; i < in_plane_nb; i++) { ppInput[i] = pInput + i * in_plane_size; } int out_plane_size = out_samples * out_ch * sizeof(float); out_samples = avresample_convert(m_pAVRCxt, (uint8_t**)&pOutput, out_plane_size, out_samples, ppInput, in_plane_size, in_samples); if (out_samples < 0) { TRACE(_T("Mixer: avresample_convert failed\n")); return 0; } return out_samples; }
void Wave64Writer::WriteData(AVFrame const& Frame) { uint64_t Length = Frame.nb_samples * BytesPerSample * Channels; if (Channels > 1 && av_sample_fmt_is_planar(static_cast<AVSampleFormat>(Frame.format))) { for (int32_t sample = 0; sample < Frame.nb_samples; ++sample) { for (int32_t channel = 0; channel < Channels; ++channel) WavFile.write(reinterpret_cast<char *>(&Frame.extended_data[channel][sample * BytesPerSample]), BytesPerSample); } } else { WavFile.write(reinterpret_cast<char *>(Frame.extended_data[0]), Length); } BytesWritten += Length; }
int CDVDAudioCodecFFmpeg::GetData(uint8_t** dst) { if(m_gotFrame) { int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? m_pFrame1->channels : 1; for (int i=0; i<planes; i++) dst[i] = m_pFrame1->extended_data[i]; m_gotFrame = 0; return m_pFrame1->nb_samples * m_pFrame1->channels * av_get_bytes_per_sample(m_pCodecContext->sample_fmt); } return 0; }
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src) { int planes, nb_channels; if (!dst) return AVERROR(EINVAL); /* abort in case the src is NULL and dst is not, avoid inconsistent state in dst */ av_assert0(src); memcpy(dst->data, src->data, sizeof(dst->data)); memcpy(dst->linesize, src->linesize, sizeof(dst->linesize)); dst->pts = src->pts; dst->format = src->format; av_frame_set_pkt_pos(dst, src->pos); switch (src->type) { case AVMEDIA_TYPE_VIDEO: av_assert0(src->video); dst->width = src->video->w; dst->height = src->video->h; dst->sample_aspect_ratio = src->video->sample_aspect_ratio; dst->interlaced_frame = src->video->interlaced; dst->top_field_first = src->video->top_field_first; dst->key_frame = src->video->key_frame; dst->pict_type = src->video->pict_type; break; case AVMEDIA_TYPE_AUDIO: av_assert0(src->audio); nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout); planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1; if (planes > FF_ARRAY_ELEMS(dst->data)) { dst->extended_data = av_mallocz_array(planes, sizeof(*dst->extended_data)); if (!dst->extended_data) return AVERROR(ENOMEM); memcpy(dst->extended_data, src->extended_data, planes * sizeof(*dst->extended_data)); } else dst->extended_data = dst->data; dst->nb_samples = src->audio->nb_samples; av_frame_set_sample_rate (dst, src->audio->sample_rate); av_frame_set_channel_layout(dst, src->audio->channel_layout); av_frame_set_channels (dst, src->audio->channels); break; default: return AVERROR(EINVAL); } return 0; }
static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; VolumeContext *vol = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; vol->sample_fmt = inlink->format; vol->channels = av_get_channel_layout_nb_channels(inlink->channel_layout); vol->planes = av_sample_fmt_is_planar(inlink->format) ? vol->channels : 1; volume_init(vol); return 0; }
static GstFlowReturn gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc, GstBuffer * buffer, gint * have_data) { GstAudioEncoder *enc; AVCodecContext *ctx; gint res; GstFlowReturn ret; GstAudioInfo *info; AVPacket *pkt; AVFrame *frame = ffmpegaudenc->frame; gboolean planar; gint nsamples = -1; enc = GST_AUDIO_ENCODER (ffmpegaudenc); ctx = ffmpegaudenc->context; pkt = g_slice_new0 (AVPacket); if (buffer != NULL) { BufferInfo *buffer_info = g_slice_new0 (BufferInfo); guint8 *audio_in; guint in_size; buffer_info->buffer = buffer; gst_buffer_map (buffer, &buffer_info->map, GST_MAP_READ); audio_in = buffer_info->map.data; in_size = buffer_info->map.size; GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer %p size:%u", audio_in, in_size); info = gst_audio_encoder_get_audio_info (enc); planar = av_sample_fmt_is_planar (ffmpegaudenc->context->sample_fmt); if (planar && info->channels > 1) { gint channels; gint i, j; nsamples = frame->nb_samples = in_size / info->bpf; channels = info->channels; frame->buf[0] = av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0); if (info->channels > AV_NUM_DATA_POINTERS) { buffer_info->ext_data_array = frame->extended_data = g_new (uint8_t *, info->channels); } else {
void interleave(uint8_t **data, uint8_t *outbuf, int channels, enum AVSampleFormat sample_fmt, int data_bytes) { assert(av_sample_fmt_is_planar(sample_fmt)); int sample_bytes = av_get_bytes_per_sample(sample_fmt); assert(data_bytes % (channels*sample_bytes) == 0); int chn_bytes = data_bytes / channels; for (int i = 0; i < chn_bytes; i+=sample_bytes) { for (int chn = 0; chn < channels; chn++) { memcpy(outbuf, data[chn]+i, sample_bytes); outbuf += sample_bytes; } } }
int static av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) { int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1; *audio_data = av_malloc(nb_planes * sizeof(**audio_data)); memset(*audio_data, 0, nb_planes * sizeof(**audio_data)); if (!*audio_data) return AVERROR(ENOMEM); ret = av_samples_alloc(*audio_data, linesize, nb_channels, nb_samples, sample_fmt, align); if (ret < 0) av_freep(audio_data); return ret; }
//resample - see http://ffmpeg.org/pipermail/libav-user/2012-June/002164.html static int resample_audio(AudioInputFile *audio_input_file, AudioInputData *audio_input_data, AVCodecContext *audio_codec_ctx, uint8_t ***output, int *num_planes_out, int num_channels, enum AVSampleFormat sample_format) { int i; *num_planes_out = av_sample_fmt_is_planar(DC_AUDIO_SAMPLE_FORMAT) ? DC_AUDIO_NUM_CHANNELS : 1; *output = (uint8_t**)av_malloc(*num_planes_out*sizeof(uint8_t*)); for (i=0; i<*num_planes_out; i++) { *output[i] = (uint8_t*)av_malloc(DC_AUDIO_MAX_CHUNCK_SIZE); //FIXME: fix using size below av_samples_get_buffer_size() } if (avresample_convert(audio_input_file->aresampler, *output, DC_AUDIO_MAX_CHUNCK_SIZE, audio_input_data->aframe->nb_samples, audio_input_data->aframe->extended_data, audio_input_data->aframe->linesize[0], audio_input_data->aframe->nb_samples) < 0) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not resample audio frame. Aborting.\n")); return -1; } return 0; }
static int calc_ptr_alignment(AVFilterBufferRef *buf) { int planes = av_sample_fmt_is_planar(buf->format) ? av_get_channel_layout_nb_channels(buf->audio->channel_layout) : 1; int min_align = 128; int p; for (p = 0; p < planes; p++) { int cur_align = 128; while ((intptr_t)buf->extended_data[p] % cur_align) cur_align >>= 1; if (cur_align < min_align) min_align = cur_align; } return min_align; }
static int calc_ptr_alignment(AVFrame *frame) { int planes = av_sample_fmt_is_planar(frame->format) ? av_get_channel_layout_nb_channels(frame->channel_layout) : 1; int min_align = 128; int p; for (p = 0; p < planes; p++) { int cur_align = 128; while ((intptr_t)frame->extended_data[p] % cur_align) cur_align >>= 1; if (cur_align < min_align) min_align = cur_align; } return min_align; }
static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; AShowInfoContext *s = ctx->priv; char chlayout_str[128]; uint32_t checksum = 0; int channels = av_get_channel_layout_nb_channels(buf->channel_layout); int planar = av_sample_fmt_is_planar(buf->format); int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels); int data_size = buf->nb_samples * block_align; int planes = planar ? channels : 1; int i; void *tmp_ptr = av_realloc(s->plane_checksums, channels * sizeof(*s->plane_checksums)); if (!tmp_ptr) return AVERROR(ENOMEM); s->plane_checksums = tmp_ptr; for (i = 0; i < planes; i++) { uint8_t *data = buf->extended_data[i]; s->plane_checksums[i] = av_adler32_update(0, data, data_size); checksum = i ? av_adler32_update(checksum, data, data_size) : s->plane_checksums[0]; } av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1, buf->channel_layout); av_log(ctx, AV_LOG_INFO, "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" " "fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d " "checksum:%08X ", inlink->frame_count, av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base), av_frame_get_pkt_pos(buf), av_get_sample_fmt_name(buf->format), av_frame_get_channels(buf), chlayout_str, buf->sample_rate, buf->nb_samples, checksum); av_log(ctx, AV_LOG_INFO, "plane_checksums: [ "); for (i = 0; i < planes; i++) av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]); av_log(ctx, AV_LOG_INFO, "]\n"); return ff_filter_frame(inlink->dst->outputs[0], buf); }
static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame ) { decoder_sys_t *p_sys = p_dec->p_sys; AVCodecContext *ctx = p_sys->p_context; block_t *p_block; /* Interleave audio if required */ if( av_sample_fmt_is_planar( ctx->sample_fmt ) ) { p_block = block_Alloc(frame->linesize[0] * ctx->channels); if ( likely(p_block) ) { const void *planes[ctx->channels]; for (int i = 0; i < ctx->channels; i++) planes[i] = frame->extended_data[i]; aout_Interleave(p_block->p_buffer, planes, frame->nb_samples, ctx->channels, p_dec->fmt_out.audio.i_format); p_block->i_nb_samples = frame->nb_samples; } av_frame_free(&frame); } else { p_block = vlc_av_frame_Wrap(frame); frame = NULL; } if (p_sys->b_extract && p_block) { /* TODO: do not drop channels... at least not here */ block_t *p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame * p_block->i_nb_samples ); if( likely(p_buffer) ) { aout_ChannelExtract( p_buffer->p_buffer, p_dec->fmt_out.audio.i_channels, p_block->p_buffer, ctx->channels, p_block->i_nb_samples, p_sys->pi_extraction, p_dec->fmt_out.audio.i_bitspersample ); p_buffer->i_nb_samples = p_block->i_nb_samples; } block_Release( p_block ); p_block = p_buffer; } return p_block; }
static int audio_write_frame(AVFormatContext *s1, int stream_index, AVFrame **frame, unsigned flags) { AlsaData *s = s1->priv_data; AVPacket pkt; /* ff_alsa_open() should have accepted only supported formats */ if ((flags & AV_WRITE_UNCODED_FRAME_QUERY)) return av_sample_fmt_is_planar(s1->streams[stream_index]->codecpar->format) ? AVERROR(EINVAL) : 0; /* set only used fields */ pkt.data = (*frame)->data[0]; pkt.size = (*frame)->nb_samples * s->frame_size; pkt.dts = (*frame)->pkt_dts; pkt.duration = (*frame)->pkt_duration; return audio_write_packet(s1, &pkt); }
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref) { AVFilterContext *ctx = inlink->dst; ShowInfoContext *showinfo = ctx->priv; uint32_t plane_checksum[8] = {0}, checksum = 0; char chlayout_str[128]; int plane; int linesize = samplesref->audio->nb_samples * av_get_bytes_per_sample(samplesref->format); if (!av_sample_fmt_is_planar(samplesref->format)) linesize *= av_get_channel_layout_nb_channels(samplesref->audio->channel_layout); for (plane = 0; samplesref->data[plane] && plane < 8; plane++) { uint8_t *data = samplesref->data[plane]; plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize); checksum = av_adler32_update(checksum, data, linesize); } av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1, samplesref->audio->channel_layout); av_log(ctx, AV_LOG_INFO, "n:%d pts:%s pts_time:%s pos:%"PRId64" " "fmt:%s chlayout:%s nb_samples:%d rate:%d " "checksum:%08X plane_checksum[%08X", showinfo->frame, av_ts2str(samplesref->pts), av_ts2timestr(samplesref->pts, &inlink->time_base), samplesref->pos, av_get_sample_fmt_name(samplesref->format), chlayout_str, samplesref->audio->nb_samples, samplesref->audio->sample_rate, checksum, plane_checksum[0]); for (plane = 1; samplesref->data[plane] && plane < 8; plane++) av_log(ctx, AV_LOG_INFO, " %08X", plane_checksum[plane]); av_log(ctx, AV_LOG_INFO, "]\n"); showinfo->frame++; ff_filter_samples(inlink->dst->outputs[0], samplesref); }
void CInfoDecoder::CopyMediaInfo1() { m_MediaInfo->m_ImportDuration = stream_duration ? stream_duration : 1; m_MediaInfo->m_Duration = stream_duration ? stream_duration : 1; m_MediaInfo->m_StreamDuration = stream_duration; m_MediaInfo->m_bVideoStream = video_stream != NULL; // 是否存在视频 m_MediaInfo->m_Width = video_width; // 视频宽 m_MediaInfo->m_Height = video_height;// 视频高 m_MediaInfo->m_CodecWidth = video_codec_width; m_MediaInfo->m_CodecHeight = video_codec_height; m_MediaInfo->m_FrameRateNum = r_frame_rate.num; // 帧率 m_MediaInfo->m_FrameRateDen = r_frame_rate.den; // 帧率 m_MediaInfo->m_VideoBitRate = video_bit_rate; m_MediaInfo->m_bAudioStream = audio_stream != NULL; // 是否存在音频 m_MediaInfo->m_SampleRate = audio_sample_rate; // 音频采样 m_MediaInfo->m_nChannel = audio_channels; // 音频通道数量 m_MediaInfo->m_channel_layout = audio_channel_layout; m_MediaInfo->m_AudioBitRate = audio_bit_rate; if (video_dec) { const AVCodecDescriptor *desc = avcodec_descriptor_get(video_dec->codec_id); if (desc) { if (desc->long_name) StringCchPrintf(m_MediaInfo->m_VideoCodec, 128, L"%hs", desc->long_name); else if (desc->name) StringCchPrintf(m_MediaInfo->m_VideoCodec, 128, L"%hs", desc->name); } m_MediaInfo->m_PixelFormat = video_dec->pix_fmt; } if (audio_dec) { const AVCodecDescriptor *desc = avcodec_descriptor_get(audio_dec->codec_id); if (desc) { if (desc->long_name) StringCchPrintf(m_MediaInfo->m_AudioCodec, 128, L"%hs", desc->long_name); else if (desc->name) StringCchPrintf(m_MediaInfo->m_AudioCodec, 128, L"%hs", desc->name); } m_MediaInfo->m_SampleFormat = audio_dec->sample_fmt; m_MediaInfo->m_IsPlanar = av_sample_fmt_is_planar(audio_format); } }
static void set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v){ uint8_t *p; if(av_sample_fmt_is_planar(f)){ f= av_get_alt_sample_fmt(f, 0); p= a[ch]; }else{ p= a[0]; index= ch + index*ch_count; } switch(f){ case AV_SAMPLE_FMT_U8 : ((uint8_t*)p)[index]= (v+1.0)*255.0/2; break; case AV_SAMPLE_FMT_S16: ((int16_t*)p)[index]= v*32767; break; case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= v*2147483647; break; case AV_SAMPLE_FMT_FLT: ((float *)p)[index]= v; break; case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v; break; default: av_assert2(0); } }
int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) { int ch, planar, buf_size; planar = av_sample_fmt_is_planar(sample_fmt); buf_size = av_samples_get_buffer_size(linesize, nb_channels, nb_samples, sample_fmt, align); if (buf_size < 0) return buf_size; audio_data[0] = buf; for (ch = 1; planar && ch < nb_channels; ch++) audio_data[ch] = audio_data[ch-1] + *linesize; return 0; }
static void audio_frame_cksum(AVBPrint *bp, AVFrame *frame) { int nb_planes, nb_samples, p; const char *name; nb_planes = av_frame_get_channels(frame); nb_samples = frame->nb_samples; if (!av_sample_fmt_is_planar(frame->format)) { nb_samples *= nb_planes; nb_planes = 1; } name = av_get_sample_fmt_name(frame->format); av_bprintf(bp, ", %d samples", frame->nb_samples); av_bprintf(bp, ", %s", name ? name : "unknown"); for (p = 0; p < nb_planes; p++) { uint32_t cksum = 0; void *d = frame->extended_data[p]; switch (frame->format) { case AV_SAMPLE_FMT_U8: case AV_SAMPLE_FMT_U8P: cksum_line_u8(&cksum, d, nb_samples); break; case AV_SAMPLE_FMT_S16: case AV_SAMPLE_FMT_S16P: cksum_line_s16(&cksum, d, nb_samples); break; case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_S32P: cksum_line_s32(&cksum, d, nb_samples); break; case AV_SAMPLE_FMT_FLT: case AV_SAMPLE_FMT_FLTP: cksum_line_flt(&cksum, d, nb_samples); break; case AV_SAMPLE_FMT_DBL: case AV_SAMPLE_FMT_DBLP: cksum_line_dbl(&cksum, d, nb_samples); break; default: av_assert0(!"reached"); } av_bprintf(bp, ", 0x%08x", cksum); } }
void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); AVFilterPad *dst = link->dstpad; int64_t pts; FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1); if (!(filter_samples = dst->filter_samples)) filter_samples = ff_default_filter_samples; /* prepare to copy the samples if the buffer has insufficient permissions */ if ((dst->min_perms & samplesref->perms) != dst->min_perms || dst->rej_perms & samplesref->perms) { int i, size, planar = av_sample_fmt_is_planar(samplesref->format); int planes = !planar ? 1: av_get_channel_layout_nb_channels(samplesref->audio->channel_layout); av_log(link->dst, AV_LOG_DEBUG, "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n", samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms); link->cur_buf = ff_default_get_audio_buffer(link, dst->min_perms, samplesref->audio->nb_samples); link->cur_buf->pts = samplesref->pts; link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate; /* Copy actual data into new samples buffer */ /* src can be larger than dst if it was allocated larger than necessary. dst can be slightly larger due to extra alignment padding. */ size = FFMIN(samplesref->linesize[0], link->cur_buf->linesize[0]); for (i = 0; samplesref->data[i] && i < 8; i++) memcpy(link->cur_buf->data[i], samplesref->data[i], size); for (i = 0; i < planes; i++) memcpy(link->cur_buf->extended_data[i], samplesref->extended_data[i], size); avfilter_unref_buffer(samplesref); } else link->cur_buf = samplesref; pts = link->cur_buf->pts; filter_samples(link, link->cur_buf); ff_update_link_current_pts(link, pts); }
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src) { int planes, nb_channels; memcpy(dst->data, src->data, sizeof(dst->data)); memcpy(dst->linesize, src->linesize, sizeof(dst->linesize)); dst->pts = src->pts; dst->format = src->format; switch (src->type) { case AVMEDIA_TYPE_VIDEO: dst->width = src->video->w; dst->height = src->video->h; dst->sample_aspect_ratio = src->video->sample_aspect_ratio; dst->interlaced_frame = src->video->interlaced; dst->top_field_first = src->video->top_field_first; dst->key_frame = src->video->key_frame; dst->pict_type = src->video->pict_type; break; case AVMEDIA_TYPE_AUDIO: nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout); planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1; if (planes > FF_ARRAY_ELEMS(dst->data)) { dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data)); if (!dst->extended_data) return AVERROR(ENOMEM); memcpy(dst->extended_data, src->extended_data, planes * sizeof(dst->extended_data)); } else dst->extended_data = dst->data; dst->sample_rate = src->audio->sample_rate; dst->channel_layout = src->audio->channel_layout; dst->nb_samples = src->audio->nb_samples; break; default: return AVERROR(EINVAL); } return 0; }