Created
March 7, 2014 21:12
-
-
Save victusfate/9420226 to your computer and use it in GitHub Desktop.
another ffmpeg libav encoding example source http://stackoverflow.com/questions/13290413/why-decoding-frames-from-avi-container-and-encode-them-to-h264-mp4-doesnt-work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern "C" { | |
#include <libavformat/avformat.h> | |
#include <libavcodec/avcodec.h> | |
#include <libavutil/avutil.h> | |
} | |
int main(int argc, char* argv[]) | |
{ | |
const char * kInputFileName = "f:/Projects/Temp/testFFMPEG2/test/test_in.avi"; | |
const char * kOutputFileName = "f:/Projects/Temp/testFFMPEG2/test/text_out.avi"; | |
const char * kOutputFileType = "avi"; | |
av_register_all(); | |
AVFormatContext * inCtx = NULL; | |
int err = avformat_open_input(&inCtx, kInputFileName, NULL, NULL); | |
if (err < 0) | |
exit(1); | |
err = av_find_stream_info(inCtx); | |
if (err < 0) | |
exit(1); | |
int vs = -1; | |
for (unsigned int s = 0; s < inCtx->nb_streams; ++s) | |
{ | |
if (inCtx->streams[s] && | |
inCtx->streams[s]->codec && | |
inCtx->streams[s]->codec->codec_type == AVMEDIA_TYPE_VIDEO) | |
{ | |
vs = s; | |
break; | |
} | |
} | |
if (vs == -1) | |
exit(1); | |
AVOutputFormat * outFmt = av_guess_format(kOutputFileType, NULL, NULL); | |
if (!outFmt) | |
exit(1); | |
AVFormatContext *outCtx = NULL; | |
err = avformat_alloc_output_context2(&outCtx, outFmt, NULL, NULL); | |
if (err < 0 || !outCtx) | |
exit(1); | |
AVStream * outStrm = av_new_stream(outCtx, 0); | |
AVStream const * const inStrm = inCtx->streams[vs]; | |
AVCodec * codec = NULL; | |
avcodec_get_context_defaults3(outStrm->codec, codec); | |
outStrm->codec->thread_count = 1; | |
#if (LIBAVFORMAT_VERSION_MAJOR == 53) | |
outStrm->stream_copy = 1; | |
#endif | |
outStrm->codec->coder_type = AVMEDIA_TYPE_VIDEO; | |
if(outCtx->oformat->flags & AVFMT_GLOBALHEADER) | |
outStrm->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; | |
outStrm->codec->sample_aspect_ratio = outStrm->sample_aspect_ratio = inStrm->sample_aspect_ratio; | |
#if (LIBAVFORMAT_VERSION_MAJOR == 53) | |
outCtx->timestamp = 0; | |
#endif | |
err = avio_open(&outCtx->pb, kOutputFileName, AVIO_FLAG_WRITE); | |
if (err < 0) | |
exit(1); | |
#if (LIBAVFORMAT_VERSION_MAJOR == 53) | |
AVFormatParameters params = {0}; | |
err = av_set_parameters(outCtx, ¶ms); | |
if (err < 0) | |
exit(1); | |
#endif | |
outStrm->disposition = inStrm->disposition; | |
outStrm->codec->bits_per_raw_sample = inStrm->codec->bits_per_raw_sample; | |
outStrm->codec->chroma_sample_location = inStrm->codec->chroma_sample_location; | |
outStrm->codec->codec_id = inStrm->codec->codec_id; | |
outStrm->codec->codec_type = inStrm->codec->codec_type; | |
if (!outStrm->codec->codec_tag) | |
{ | |
if (! outCtx->oformat->codec_tag | |
|| av_codec_get_id (outCtx->oformat->codec_tag, inStrm->codec->codec_tag) == outStrm->codec->codec_id | |
|| av_codec_get_tag(outCtx->oformat->codec_tag, inStrm->codec->codec_id) <= 0) | |
outStrm->codec->codec_tag = inStrm->codec->codec_tag; | |
} | |
outStrm->codec->bit_rate = inStrm->codec->bit_rate; | |
outStrm->codec->rc_max_rate = inStrm->codec->rc_max_rate; | |
outStrm->codec->rc_buffer_size = inStrm->codec->rc_buffer_size; | |
const size_t extra_size_alloc = (inStrm->codec->extradata_size > 0) ? | |
(inStrm->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE) : | |
0; | |
if (extra_size_alloc) | |
{ | |
outStrm->codec->extradata = (uint8_t*)av_mallocz(extra_size_alloc); | |
memcpy( outStrm->codec->extradata, inStrm->codec->extradata, inStrm->codec->extradata_size); | |
} | |
outStrm->codec->extradata_size = inStrm->codec->extradata_size; | |
AVRational input_time_base = inStrm->time_base; | |
AVRational frameRate = {25, 1}; | |
if (inStrm->r_frame_rate.num && inStrm->r_frame_rate.den | |
&& (1.0 * inStrm->r_frame_rate.num / inStrm->r_frame_rate.den < 1000.0)) | |
{ | |
frameRate.num = inStrm->r_frame_rate.num; | |
frameRate.den = inStrm->r_frame_rate.den; | |
} | |
outStrm->r_frame_rate = frameRate; | |
outStrm->codec->time_base = inStrm->codec->time_base; | |
outStrm->codec->pix_fmt = inStrm->codec->pix_fmt; | |
outStrm->codec->width = inStrm->codec->width; | |
outStrm->codec->height = inStrm->codec->height; | |
outStrm->codec->has_b_frames = inStrm->codec->has_b_frames; | |
if (! outStrm->codec->sample_aspect_ratio.num) { | |
AVRational r0 = {0, 1}; | |
outStrm->codec->sample_aspect_ratio = | |
outStrm->sample_aspect_ratio = | |
inStrm->sample_aspect_ratio.num ? inStrm->sample_aspect_ratio : | |
inStrm->codec->sample_aspect_ratio.num ? | |
inStrm->codec->sample_aspect_ratio : r0; | |
} | |
#if LIBAVFORMAT_VERSION_MAJOR == 53 | |
av_write_header(outFmtCtx); | |
#else | |
avformat_write_header(outCtx, NULL); | |
#endif | |
for (;;) | |
{ | |
AVPacket packet = {0}; | |
av_init_packet(&packet); | |
err = AVERROR(EAGAIN); | |
while (AVERROR(EAGAIN) == err) | |
err = av_read_frame(inCtx, &packet); | |
if (err < 0) | |
{ | |
if (AVERROR_EOF != err && AVERROR(EIO) != err) | |
{ | |
// error | |
exit(1); | |
} | |
else | |
{ | |
// end of file | |
break; | |
} | |
} | |
if (packet.stream_index == vs) | |
{ | |
err = av_interleaved_write_frame(outCtx, &packet); | |
if (err < 0) | |
exit(1); | |
} | |
av_free_packet(&packet); | |
} | |
av_write_trailer(outCtx); | |
if (!(outCtx->oformat->flags & AVFMT_NOFILE) && outCtx->pb) | |
avio_close(outCtx->pb); | |
avformat_free_context(outCtx); | |
av_close_input_file(inCtx); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// find output format | |
AVOutputFormat * outputFormat = av_guess_format("mp4", NULL, NULL); | |
AVFormatContext *outFmtCtx = NULL; | |
// create output cotext | |
avformat_alloc_output_context2(&outFmtCtx, outputFormat, NULL, NULL); | |
// create new stream | |
AVStream * outStrm = avformat_new_stream(outFmtCtx, codecEncode); | |
avcodec_get_context_defaults3(outStrm->codec, *codec); | |
outStrm->codec->codec_id = codec_id; | |
outStrm->codec->coder_type = AVMEDIA_TYPE_VIDEO; | |
/// outStrm->codec-> ... | |
/// set all fields marked as "MUST be set by user" in avcodec.h | |
/// .... | |
// create file | |
avio_open2(&outFmtCtx->pb, file_name, AVIO_FLAG_WRITE, NULL, NULL); | |
avformat_write_header(outFmtCtx, NULL); | |
/// write packets | |
/// for ( ) | |
av_interleaved_write_frame(outFmtCtx, packet); | |
/// finish | |
av_write_trailer(outFmtCtx); | |
avio_close(outFmtCtx->pb); | |
avformat_free_context(outFmtCtx); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I want to decode a packet into an AVFrame, process the frame and encode it back to AVPacket. But I can't do it. Can you help me how?