AVCodec *codec = avcodec_find_decoder(codecParameters->codec_id);这句代码报错了,报错原因是error: cannot initialize a variable of type 'AVCodec *' with an rvalue of type 'const AVCodec *'
时间: 2024-03-01 13:55:16 浏览: 155
这个错误通常是因为你正在尝试初始化一个非常量指针变量,但它的初始化值是一个常量指针。这可能是由于两个不兼容的类型之间的赋值导致的。
解决这个问题的方法是将变量声明为常量指针,即:
```
const AVCodec *codec = avcodec_find_decoder(codecParameters->codec_id);
```
如果你需要在后续的代码中修改该变量,则需要将其声明为非常量指针。在这种情况下,你可以使用类型转换来解决这个问题,即:
```
AVCodec *codec = (AVCodec *) avcodec_find_decoder(codecParameters->codec_id);
```
但是,这种方法不是最佳实践,因为它可能会引入其他问题。因此,最好尽可能使用常量指针来避免这个错误。
相关问题
ffmpeg音频解码成wav格式实现代码
以下是使用FFmpeg将音频解码为WAV格式的示例代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <math.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/frame.h>
#include <libavutil/opt.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
FILE *outfile)
{
int i, ch;
int ret, data_size;
/* send the packet with the compressed data to the decoder */
ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error submitting the packet to the decoder\n");
exit(1);
}
/* read all the output frames (in general there may be any number of them) */
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
if (data_size < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
exit(1);
}
for (i = 0; i < frame->nb_samples; i++)
for (ch = 0; ch < dec_ctx->channels; ch++)
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
}
}
int main(int argc, char **argv)
{
AVCodec *codec;
AVCodecContext *codec_ctx = NULL;
AVCodecParserContext *parser = NULL;
AVFormatContext *fmt_ctx = NULL;
AVPacket *pkt = NULL;
AVFrame *frame = NULL;
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
int inbuf_size;
int64_t pts;
int ret;
int i;
if (argc <= 1) {
fprintf(stderr, "Usage: %s <input file>\n", argv[0]);
exit(0);
}
/* register all the codecs */
av_register_all();
/* allocate the input buffer */
pkt = av_packet_alloc();
if (!pkt) {
fprintf(stderr, "Failed to allocate packet\n");
exit(1);
}
/* open the input file */
ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Cannot open input file '%s'\n", argv[1]);
exit(1);
}
/* retrieve stream information */
ret = avformat_find_stream_info(fmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Cannot find stream information\n");
exit(1);
}
/* select the audio stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
if (ret < 0) {
fprintf(stderr, "Cannot find an audio stream in the input file\n");
exit(1);
}
int audio_stream_idx = ret;
/* allocate the codec context */
codec_ctx = avcodec_alloc_context3(codec);
if (!codec_ctx) {
fprintf(stderr, "Failed to allocate codec context\n");
exit(1);
}
/* fill the codec context based on the stream information */
ret = avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[audio_stream_idx]->codecpar);
if (ret < 0) {
fprintf(stderr, "Failed to copy codec parameters to codec context\n");
exit(1);
}
/* init the codec context */
ret = avcodec_open2(codec_ctx, codec, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to open codec\n");
exit(1);
}
/* allocate the frame */
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Failed to allocate frame\n");
exit(1);
}
/* init the packet parser */
parser = av_parser_init(codec_ctx->codec_id);
if (!parser) {
fprintf(stderr, "Failed to init packet parser\n");
exit(1);
}
/* open the output file */
FILE *outfile = fopen("output.wav", "wb");
if (!outfile) {
fprintf(stderr, "Failed to open output file\n");
exit(1);
}
/* read packets from the input file */
while (1) {
/* get more data from the input file */
ret = av_read_frame(fmt_ctx, pkt);
if (ret < 0)
break;
/* if this is not the audio stream, ignore it */
if (pkt->stream_index != audio_stream_idx) {
av_packet_unref(pkt);
continue;
}
/* send the packet to the parser */
inbuf_size = pkt->size;
memcpy(inbuf, pkt->data, inbuf_size);
while (inbuf_size > 0) {
ret = av_parser_parse2(parser, codec_ctx, &pkt->data, &pkt->size,
inbuf, inbuf_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
fprintf(stderr, "Error while parsing\n");
exit(1);
}
inbuf += ret;
inbuf_size -= ret;
/* if we have a complete frame, decode it */
if (pkt->size > 0) {
decode(codec_ctx, pkt, frame, outfile);
}
}
av_packet_unref(pkt);
}
/* flush the decoder */
decode(codec_ctx, NULL, frame, outfile);
/* close the output file */
fclose(outfile);
/* free the resources */
av_parser_close(parser);
avcodec_free_context(&codec_ctx);
av_frame_free(&frame);
av_packet_free(&pkt);
avformat_close_input(&fmt_ctx);
return 0;
}
```
这个程序使用FFmpeg库将音频文件解码为WAV格式,并将解码后的数据写入到一个输出文件中。你可以将输入文件的路径作为程序的参数来运行它。
使用ffmpg 实现rtmp 推音频流的C++代码
以下是使用FFmpeg实现RTMP推送音频流的C++代码示例:
```c++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/opt.h>
#include <libavutil/error.h>
#include <libavutil/mathematics.h>
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
int main(int argc, char **argv)
{
AVOutputFormat *ofmt = NULL;
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVPacket pkt;
AVCodecContext *dec_ctx = NULL, *enc_ctx = NULL;
AVCodec *encoder = NULL;
int stream_index = 0;
int ret = 0;
int64_t cur_pts = 0;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data = NULL;
int data_size = 0;
const char *out_filename = "rtmp://localhost:1935/live/stream";
const char *in_filename = "test.mp3";
av_register_all();
// Open input file context
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
goto end;
}
// Retrieve stream information
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
goto end;
}
// Dump input information
av_dump_format(ifmt_ctx, 0, in_filename, 0);
// Open output file context
if ((ret = avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_filename)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create output context\n");
goto end;
}
ofmt = ofmt_ctx->oformat;
// Add audio stream to output context
for (int i = 0; i < ifmt_ctx->nb_streams; i++) {
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
AVStream *in_stream = ifmt_ctx->streams[i];
dec_ctx = avcodec_alloc_context3(NULL);
if (!dec_ctx) {
av_log(NULL, AV_LOG_ERROR, "Failed to allocate decoder context\n");
goto end;
}
ret = avcodec_parameters_to_context(dec_ctx, in_stream->codecpar);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context\n");
goto end;
}
encoder = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (!encoder) {
av_log(NULL, AV_LOG_ERROR, "Codec not found\n");
goto end;
}
enc_ctx = avcodec_alloc_context3(encoder);
if (!enc_ctx) {
av_log(NULL, AV_LOG_ERROR, "Failed to allocate encoder context\n");
goto end;
}
enc_ctx->channels = dec_ctx->channels;
enc_ctx->channel_layout = dec_ctx->channel_layout;
enc_ctx->sample_rate = dec_ctx->sample_rate;
enc_ctx->sample_fmt = encoder->sample_fmts[0];
enc_ctx->bit_rate = 128000;
if (ofmt->flags & AVFMT_GLOBALHEADER) {
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
ret = avcodec_open2(enc_ctx, encoder, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open encoder\n");
goto end;
}
AVStream *out_stream = avformat_new_stream(ofmt_ctx, encoder);
if (!out_stream) {
av_log(NULL, AV_LOG_ERROR, "Failed to allocate output stream\n");
goto end;
}
ret = avcodec_parameters_copy(out_stream->codecpar, enc_ctx->codecpar);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream\n");
goto end;
}
out_stream->codecpar->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) {
out_stream->codecpar->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
stream_index = out_stream->index;
break;
}
}
// Dump output information
av_dump_format(ofmt_ctx, 0, out_filename, 1);
// Open output file
if (!(ofmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open output file\n");
goto end;
}
}
// Write header to output file
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
goto end;
}
// Read frames from input file and write to output file
while (1) {
AVStream *in_stream, *out_stream;
// Read packet from input file
ret = av_read_frame(ifmt_ctx, &pkt);
if (ret < 0) {
break;
}
// Ignore packets that do not belong to the audio stream
if (pkt.stream_index != stream_index) {
av_packet_unref(&pkt);
continue;
}
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[pkt.stream_index];
// Calculate packet duration
AVRational time_base = in_stream->time_base;
int64_t pts_time = av_rescale_q(pkt.pts, time_base, AV_TIME_BASE_Q);
int64_t now_time = av_gettime() - cur_pts;
if (now_time < pts_time) {
av_usleep(pts_time - now_time);
}
// Decode audio frame
ret = avcodec_send_packet(dec_ctx, &pkt);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error sending packet to decoder\n");
goto end;
}
while (ret >= 0) {
AVFrame *decoded_frame = av_frame_alloc();
if (!decoded_frame) {
av_log(NULL, AV_LOG_ERROR, "Failed to allocate memory for decoded frame\n");
goto end;
}
ret = avcodec_receive_frame(dec_ctx, decoded_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
av_frame_free(&decoded_frame);
break;
} else if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error receiving frame from decoder\n");
goto end;
}
// Encode audio frame
AVPacket enc_pkt;
av_init_packet(&enc_pkt);
enc_pkt.data = NULL;
enc_pkt.size = 0;
ret = avcodec_send_frame(enc_ctx, decoded_frame);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error sending frame to encoder\n");
goto end;
}
while (ret >= 0) {
ret = avcodec_receive_packet(enc_ctx, &enc_pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error receiving packet from encoder\n");
goto end;
}
// Write packet to output file
av_packet_rescale_ts(&enc_pkt, enc_ctx->time_base, out_stream->time_base);
enc_pkt.stream_index = stream_index;
ret = av_write_frame(ofmt_ctx, &enc_pkt);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing audio frame\n");
goto end;
}
av_packet_unref(&enc_pkt);
}
av_frame_free(&decoded_frame);
}
av_packet_unref(&pkt);
}
// Flush encoders
ret = avcodec_send_frame(enc_ctx, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error sending null frame to encoder\n");
goto end;
}
while (ret >= 0) {
AVPacket enc_pkt;
av_init_packet(&enc_pkt);
enc_pkt.data = NULL;
enc_pkt.size = 0;
ret = avcodec_receive_packet(enc_ctx, &enc_pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error receiving packet from encoder\n");
goto end;
}
av_packet_rescale_ts(&enc_pkt, enc_ctx->time_base, ofmt_ctx->streams[stream_index]->time_base);
enc_pkt.stream_index = stream_index;
ret = av_write_frame(ofmt_ctx, &enc_pkt);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing audio frame\n");
goto end;
}
av_packet_unref(&enc_pkt);
}
// Write trailer to output file
av_write_trailer(ofmt_ctx);
end:
avcodec_free_context(&dec_ctx);
avcodec_free_context(&enc_ctx);
avformat_close_input(&ifmt_ctx);
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE)) {
avio_closep(&ofmt_ctx->pb);
}
avformat_free_context(ofmt_ctx);
if (ret < 0) {
char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
av_strerror(ret, errbuf, sizeof(errbuf));
av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", errbuf);
return 1;
}
return 0;
}
```
这段代码假设输入文件为MP3格式,输出文件为FLV格式,并且只包含一个音频流。代码将音频流从输入文件中解码,并使用AAC编码器编码成AAC格式,然后将编码后的音频流写入输出文件。在实际使用时,你需要根据你的需求进行相应的修改。
阅读全文