X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=doc%2Fexamples%2Fmuxing.c;h=fe1b9ded2103bb5df62dfae86510534fa5181799;hb=626535f6a169e2d821b969e0ea77125ba7482113;hp=08da98e574a91fcc364b8432a095870e74facb1c;hpb=d6b62ce1aced9e2456582870382f384581cc7cbb;p=ffmpeg diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c index 08da98e574a..fe1b9ded210 100644 --- a/doc/examples/muxing.c +++ b/doc/examples/muxing.c @@ -78,20 +78,50 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt) pkt->stream_index); } -static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt) +static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c, + AVStream *st, AVFrame *frame) { - /* rescale output packet timestamp values from codec to stream timebase */ - av_packet_rescale_ts(pkt, *time_base, st->time_base); - pkt->stream_index = st->index; + int ret; + + // send the frame to the encoder + ret = avcodec_send_frame(c, frame); + if (ret < 0) { + fprintf(stderr, "Error sending a frame to the encoder: %s\n", + av_err2str(ret)); + exit(1); + } + + while (ret >= 0) { + AVPacket pkt = { 0 }; - /* Write the compressed frame to the media file. */ - log_packet(fmt_ctx, pkt); - return av_interleaved_write_frame(fmt_ctx, pkt); + ret = avcodec_receive_packet(c, &pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + break; + else if (ret < 0) { + fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret)); + exit(1); + } + + /* rescale output packet timestamp values from codec to stream timebase */ + av_packet_rescale_ts(&pkt, c->time_base, st->time_base); + pkt.stream_index = st->index; + + /* Write the compressed frame to the media file. */ + log_packet(fmt_ctx, &pkt); + ret = av_interleaved_write_frame(fmt_ctx, &pkt); + av_packet_unref(&pkt); + if (ret < 0) { + fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret)); + exit(1); + } + } + + return ret == AVERROR_EOF ? 1 : 0; } /* Add an output stream. */ static void add_stream(OutputStream *ost, AVFormatContext *oc, - AVCodec **codec, + const AVCodec **codec, enum AVCodecID codec_id) { AVCodecContext *c; @@ -170,7 +200,7 @@ static void add_stream(OutputStream *ost, AVFormatContext *oc, * the motion of the chroma plane does not match the luma plane. */ c->mb_decision = 2; } - break; + break; default: break; @@ -212,7 +242,8 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, return frame; } -static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg) +static void open_audio(AVFormatContext *oc, const AVCodec *codec, + OutputStream *ost, AVDictionary *opt_arg) { AVCodecContext *c; int nb_samples; @@ -254,25 +285,25 @@ static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, A } /* create resampler context */ - ost->swr_ctx = swr_alloc(); - if (!ost->swr_ctx) { - fprintf(stderr, "Could not allocate resampler context\n"); - exit(1); - } + ost->swr_ctx = swr_alloc(); + if (!ost->swr_ctx) { + fprintf(stderr, "Could not allocate resampler context\n"); + exit(1); + } - /* set options */ - av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); - av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0); - av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); - av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); - av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); - av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); - - /* initialize the resampling context */ - if ((ret = swr_init(ost->swr_ctx)) < 0) { - fprintf(stderr, "Failed to initialize the resampling context\n"); - exit(1); - } + /* set options */ + av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); + av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0); + av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); + av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); + av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); + av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); + + /* initialize the resampling context */ + if ((ret = swr_init(ost->swr_ctx)) < 0) { + fprintf(stderr, "Failed to initialize the resampling context\n"); + exit(1); + } } /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and @@ -285,7 +316,7 @@ static AVFrame *get_audio_frame(OutputStream *ost) /* check if we want to generate more frames */ if (av_compare_ts(ost->next_pts, ost->enc->time_base, - STREAM_DURATION, (AVRational){ 1, 1 }) >= 0) + STREAM_DURATION, (AVRational){ 1, 1 }) > 0) return NULL; for (j = 0; j nb_samples; j++) { @@ -309,23 +340,20 @@ static AVFrame *get_audio_frame(OutputStream *ost) static int write_audio_frame(AVFormatContext *oc, OutputStream *ost) { AVCodecContext *c; - AVPacket pkt = { 0 }; // data and size must be 0; AVFrame *frame; int ret; - int got_packet; int dst_nb_samples; - av_init_packet(&pkt); c = ost->enc; frame = get_audio_frame(ost); if (frame) { /* convert samples from native format to destination codec format, using the resampler */ - /* compute destination number of samples */ - dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples, - c->sample_rate, c->sample_rate, AV_ROUND_UP); - av_assert0(dst_nb_samples == frame->nb_samples); + /* compute destination number of samples */ + dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples, + c->sample_rate, c->sample_rate, AV_ROUND_UP); + av_assert0(dst_nb_samples == frame->nb_samples); /* when we pass a frame to the encoder, it may keep a reference to it * internally; @@ -349,22 +377,7 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost) ost->samples_count += dst_nb_samples; } - ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet); - if (ret < 0) { - fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret)); - exit(1); - } - - if (got_packet) { - ret = write_frame(oc, &c->time_base, ost->st, &pkt); - if (ret < 0) { - fprintf(stderr, "Error while writing audio frame: %s\n", - av_err2str(ret)); - exit(1); - } - } - - return (frame || got_packet) ? 0 : 1; + return write_frame(oc, c, ost->st, frame); } /**************************************************************/ @@ -384,7 +397,7 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height) picture->height = height; /* allocate the buffers for the frame data */ - ret = av_frame_get_buffer(picture, 32); + ret = av_frame_get_buffer(picture, 0); if (ret < 0) { fprintf(stderr, "Could not allocate frame data.\n"); exit(1); @@ -393,7 +406,8 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height) return picture; } -static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg) +static void open_video(AVFormatContext *oc, const AVCodec *codec, + OutputStream *ost, AVDictionary *opt_arg) { int ret; AVCodecContext *c = ost->enc; @@ -464,7 +478,7 @@ static AVFrame *get_video_frame(OutputStream *ost) /* check if we want to generate more frames */ if (av_compare_ts(ost->next_pts, c->time_base, - STREAM_DURATION, (AVRational){ 1, 1 }) >= 0) + STREAM_DURATION, (AVRational){ 1, 1 }) > 0) return NULL; /* when we pass a frame to the encoder, it may keep a reference to it @@ -506,37 +520,7 @@ static AVFrame *get_video_frame(OutputStream *ost) */ static int write_video_frame(AVFormatContext *oc, OutputStream *ost) { - int ret; - AVCodecContext *c; - AVFrame *frame; - int got_packet = 0; - AVPacket pkt = { 0 }; - - c = ost->enc; - - frame = get_video_frame(ost); - - av_init_packet(&pkt); - - /* encode the image */ - ret = avcodec_encode_video2(c, &pkt, frame, &got_packet); - if (ret < 0) { - fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret)); - exit(1); - } - - if (got_packet) { - ret = write_frame(oc, &c->time_base, ost->st, &pkt); - } else { - ret = 0; - } - - if (ret < 0) { - fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret)); - exit(1); - } - - return (frame || got_packet) ? 0 : 1; + return write_frame(oc, ost->enc, ost->st, get_video_frame(ost)); } static void close_stream(AVFormatContext *oc, OutputStream *ost) @@ -554,10 +538,10 @@ static void close_stream(AVFormatContext *oc, OutputStream *ost) int main(int argc, char **argv) { OutputStream video_st = { 0 }, audio_st = { 0 }; + const AVOutputFormat *fmt; const char *filename; - AVOutputFormat *fmt; AVFormatContext *oc; - AVCodec *audio_codec, *video_codec; + const AVCodec *audio_codec, *video_codec; int ret; int have_video = 0, have_audio = 0; int encode_video = 0, encode_audio = 0;