Skip to content

Instantly share code, notes, and snippets.

@csimsek
Created Dec 3, 2015
Embed
What would you like to do?
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#include <libavdevice/avdevice.h>
#include <stdio.h>
AVFormatContext *output_context, *input_context;
AVCodecContext *input_codec_context, *output_codec_context;
AVOutputFormat *output_format;
AVCodec *input_codec, *output_codec;
int input_video_stream_index = -1;
AVFrame *input_frame, *output_frame, *rgb_frame;
AVStream *video_stream;
int in_w=480,in_h=272;
void error(const char *message) {
fprintf(stderr, "%s\n", message);
exit(1);
}
/* select layout with the highest channel count */
static int select_channel_layout(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;
}
/* just pick the highest supported samplerate */
static int select_sample_rate(AVCodec *codec)
{
const int *p;
int best_samplerate = 0;
if (!codec->supported_samplerates)
return 44100;
p = codec->supported_samplerates;
while (*p) {
best_samplerate = FFMAX(*p, best_samplerate);
p++;
}
return best_samplerate;
}
int find_video_stream_index(AVFormatContext *input_context) {
for (int i = 0; i < input_context->nb_streams; i++) {
if (input_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
return i;
}
}
error("video stream bulunamadi");
return 0;
}
void init_input_codec() {
input_codec_context = input_context->streams[input_video_stream_index]->codec;
input_codec = avcodec_find_decoder(input_codec_context->codec_id);
if (!input_codec) {
error("input codec bulunamadi");
}
//input_codec_context = avformat_alloc_context3(input_codec);
if (avcodec_open2(input_codec_context, input_codec, NULL) < 0) {
error("avcodec_open2");
}
}
void init_output_codec(const char *outputstream) {
output_format = av_guess_format(NULL, outputstream, NULL);
output_context = avformat_alloc_context();
output_context->oformat = output_format;
//avformat_alloc_output_context2(&output_context, NULL, NULL, outputstream);
if (output_context == NULL) {
error("output context olusturulamadi");
}
video_stream = avformat_new_stream(output_context, 0);
if (!video_stream) {
error("video_stream olusturulamadi");
}
video_stream->time_base.num = 1;
video_stream->time_base.den = 25;
output_codec_context = video_stream->codec;
/* put sample parameters */
// output_codec_context->codec_id = AV_CODEC_ID_MPEG1VIDEO;
output_codec_context->bit_rate = 400000;
/* resolution must be a multiple of two */
output_codec_context->width = in_h;
output_codec_context->height = in_w;
/* frames per second */
output_codec_context->time_base= (AVRational){1,25};
output_codec_context->gop_size = 10; /* emit one intra frame every ten frames */
output_codec_context->max_b_frames=1;
output_codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
output_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!output_codec) {
error("output codec couldn't find");
}
av_dump_format(output_context, 0, outputstream, 1);
if (avcodec_open2(output_codec_context, output_codec, NULL) < 0) {
error("codec open error");
}
avio_open(&output_context->pb, outputstream, AVIO_FLAG_READ_WRITE);
if (avformat_write_header(output_context, NULL) < 0) {
error("avformat_write_header error");
}
}
void init_all(const char *inputstream, const char *outputstream) {
av_register_all();
avdevice_register_all();
avcodec_register_all();
avformat_network_init();
if (avformat_open_input(&input_context, inputstream, NULL, NULL) != 0) {
error("avformat_open_input error");
}
if (avformat_find_stream_info(input_context, NULL) < 0) {
error("avformat_find_stream_info error");
}
input_video_stream_index = find_video_stream_index(input_context);
printf("video index : %d\n", input_video_stream_index);
init_input_codec();
init_output_codec(outputstream);
input_frame = av_frame_alloc();
rgb_frame = av_frame_alloc();
}
void save_frame(AVFrame *frame, int in_w, int in_h) {
AVPacket pkt;
int got_frame;
int ret;
av_init_packet(&pkt);
pkt.size = 0;
pkt.data = NULL;
frame->width = in_w;
frame->height = in_h;
frame->nb_samples = output_codec_context->frame_size;
frame->format = output_codec_context->sample_fmt;
frame->channel_layout = output_codec_context->channel_layout;
printf("frame encode ediliyor\n");
ret = avcodec_encode_video2(output_codec_context, &pkt, frame, &got_frame);
if (ret < 0) {
error("encoding error");
}
if (got_frame) {
av_write_frame(output_context, &pkt);
av_free_packet(&pkt);
}
}
void start_all(void) {
AVPacket packet;
int frame_number = 0;
uint8_t *buffer = NULL;
int numBytes;
struct SwsContext *sws_ctx = NULL;
numBytes=avpicture_get_size(PIX_FMT_RGB24, input_codec_context->width,
input_codec_context->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)rgb_frame, buffer, PIX_FMT_RGB24,
input_codec_context->width, input_codec_context->height);
sws_ctx = sws_getContext(input_codec_context->width,
input_codec_context->height,
input_codec_context->pix_fmt,
input_codec_context->width,
input_codec_context->height,
PIX_FMT_RGB24,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
while (av_read_frame(input_context, &packet) >= 0) {
if (packet.stream_index == input_video_stream_index) {
int frame_finished;
avcodec_decode_video2(input_codec_context, input_frame, &frame_finished, &packet);
if (frame_finished) {
sws_scale(sws_ctx, (uint8_t const * const *)input_frame->data,
input_frame->linesize, 0, input_codec_context->height,
rgb_frame->data, rgb_frame->linesize);
save_frame(rgb_frame, in_h, in_w);
}
}
av_free_packet(&packet);
}
}
int main(void) {
char *inputstream = "input.mp4";
char *outputstream = "output.mp4";
init_all(inputstream, outputstream);
start_all();
av_write_trailer(output_context);
avio_close(output_context->pb);
avformat_free_context(output_context);
avformat_free_context(input_context);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment