How to convert from pcm to mp3 on ffmpeg 4.0?

Examples and samples for those who develop software with FFmpeg.
Post Reply
aaadddzxc
Posts: 1
Joined: Sun Sep 02, 2018 4:27 am

How to convert from pcm to mp3 on ffmpeg 4.0?

Post by aaadddzxc » Sun Sep 02, 2018 4:34 am

Play sound through "ffplay.exe tdjm.pcm -f f32le -ar 44100 -ac 2" is ok
But there is a problem with the code to mp3,as follows:

Code: Select all


#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/frame.h>
#include <libavutil/samplefmt.h>
}

#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avdevice.lib")
#pragma comment(lib,"avfilter.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"postproc.lib")
#pragma comment(lib,"swresample.lib")
#pragma comment(lib,"swscale.lib")

  /* check that a given sample format is supported by the encoder */
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
{
	const enum AVSampleFormat *p = codec->sample_fmts;

	while (*p != AV_SAMPLE_FMT_NONE) {
		if (*p == sample_fmt)
			return 1;
		p++;
	}
	return 0;
}

/* just pick the highest supported samplerate */
static int select_sample_rate(const AVCodec *codec)
{
	const int *p;
	int best_samplerate = 0;

	if (!codec->supported_samplerates)
		return 44100;

	p = codec->supported_samplerates;
	while (*p) {
		if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
			best_samplerate = *p;
		p++;
	}
	return best_samplerate;
}

/* select layout with the highest channel count */
static int select_channel_layout(const AVCodec *codec)
{
	const uint64_t *p;
	uint64_t best_ch_layout = 0;
	int best_nb_channels = 0;

	if (!codec->channel_layouts)
		return AV_CH_LAYOUT_STEREO;

	p = codec->channel_layouts;
	while (*p) {
		int nb_channels = av_get_channel_layout_nb_channels(*p);

		if (nb_channels > best_nb_channels) {
			best_ch_layout = *p;
			best_nb_channels = nb_channels;
		}
		p++;
	}
	return best_ch_layout;
}

static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
	FILE *output)
{
	int ret;

	/* send the frame for encoding */
	ret = avcodec_send_frame(ctx, frame);
	if (ret < 0) {
		fprintf(stderr, "Error sending the frame to the encoder\n");
		exit(1);
	}

	/* read all the available output packets (in general there may be any
	 * number of them */
	while (ret >= 0) {
		ret = avcodec_receive_packet(ctx, pkt);
		if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
			return;
		else if (ret < 0) {
			fprintf(stderr, "Error encoding audio frame\n");
			exit(1);
		}

		fwrite(pkt->data, 1, pkt->size, output);
		av_packet_unref(pkt);
	}
}

int main(int argc, char **argv)
{
	const char *filename;
	const char *outfilename;
	const AVCodec *codec;
	AVCodecContext *c = NULL;
	AVFrame *frame;
	AVPacket *pkt;
	int ret;
	FILE *fp;
	FILE *fpout;

	filename = "H:\\Debug\\tdjm.pcm";
	outfilename = "H:\\Debug\\tdjm1.mp3";
	fp = fopen(filename, "rb");
	if (!fp) {
		fprintf(stderr, "Could not open %s\n", filename);
		exit(1);
	}
	fpout = fopen(outfilename, "wb");
	if (!fpout) {
		exit(1);
	}

	/* find the MP2 encoder */
	codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
	if (!codec) {
		fprintf(stderr, "Codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context3(codec);
	if (!c) {
		fprintf(stderr, "Could not allocate audio codec context\n");
		exit(1);
	}

	/* put sample parameters */
	c->bit_rate = 64000;

	/* check that the encoder supports s16 pcm input */
	c->sample_fmt = *codec->sample_fmts;
	if (!check_sample_fmt(codec, c->sample_fmt)) {
		fprintf(stderr, "Encoder does not support sample format %s",
			av_get_sample_fmt_name(c->sample_fmt));
		exit(1);
	}

	/* select other audio parameters supported by the encoder */
	c->sample_rate = select_sample_rate(codec);
	c->channel_layout = select_channel_layout(codec);
	c->channels = av_get_channel_layout_nb_channels(c->channel_layout);

	/* open it */
	if (avcodec_open2(c, codec, NULL) < 0) {
		fprintf(stderr, "Could not open codec\n");
		exit(1);
	}

	/* packet for holding encoded output */
	pkt = av_packet_alloc();
	if (!pkt) {
		fprintf(stderr, "could not allocate the packet\n");
		exit(1);
	}

	/* frame containing input raw audio */
	frame = av_frame_alloc();
	if (!frame) {
		fprintf(stderr, "Could not allocate audio frame\n");
		exit(1);
	}

	frame->nb_samples = c->frame_size;
	frame->format = c->sample_fmt;
	frame->channel_layout = c->channel_layout;

	/* allocate the data buffers */
	ret = av_frame_get_buffer(frame, 0);
	if (ret < 0) {
		fprintf(stderr, "Could not allocate audio data buffers\n");
		exit(1);
	}


	while (1)
	{
		char tszMsgBuffer[2048];
		memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer));
		int nRet = fread(tszMsgBuffer, 1, sizeof(tszMsgBuffer), fp);
		if (nRet <= 0)
		{
			break;
		}
		ret = av_frame_make_writable(frame);
		if (ret < 0)
			exit(1);
		memcpy(frame->data[0], tszMsgBuffer, nRet);

		encode(c, frame, pkt, fpout);
	}

	/* flush the encoder */
	encode(c, NULL, pkt, fpout);

	fclose(fp);
	fclose(fpout);

	av_frame_free(&frame);
	av_packet_free(&pkt);
	avcodec_free_context(&c);

	return 0;
}
who knows?

Post Reply
'