+#include "libavformat/avformat.h"
+#include "libavcodec/avcodec.h"
+#include "libswscale/swscale.h"
+
+struct resample_data {
+ struct SwsContext *resample_ctx;
+ int in_height;
+ AVFrame resampled_frame;
+};
+
+int codec_open(AVFormatContext *ctx)
+{
+ AVCodec *codec;
+ int i, res;
+
+ for (i = 0; i < ctx->nb_streams; i++) {
+ codec = avcodec_find_decoder(ctx->streams[i]->codec->codec_id);
+ if (!codec) {
+ fprintf(stderr, "Cannot find codec %d for input stream %d\n",
+ ctx->streams[i]->codec->codec_id, i);
+ return -1;
+ }
+ res = avcodec_open(ctx->streams[i]->codec, codec);
+ if (res < 0) {
+ fprintf(stderr, "Cannot open codec for input stream %d\n", i);
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int out_codec_open(AVFormatContext *ctx)
+{
+ AVCodec *codec;
+ int i, res;
+
+ for (i = 0; i < ctx->nb_streams; i++) {
+ codec = avcodec_find_encoder(ctx->streams[i]->codec->codec_id);
+ if (!codec) {
+ fprintf(stderr, "Cannot find codec %d for output stream %d\n",
+ ctx->streams[i]->codec->codec_id, i);
+ return -1;
+ }
+ res = avcodec_open(ctx->streams[i]->codec, codec);
+ if (res < 0) {
+ fprintf(stderr, "Cannot open codec for input stream %d\n", i);
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+AVFrame *pkt_decode(AVFormatContext *ctx, AVPacket *pkt)
+{
+ static AVFrame frame;
+ int res, got;
+
+ avcodec_get_frame_defaults(&frame);
+ res = avcodec_decode_video(ctx->streams[pkt->stream_index]->codec,
+ &frame, &got, pkt->data, pkt->size);
+ if (res < 0) {
+ got = res;
+ }
+
+ if (got > 0) {
+ AVFrame *res;
+ struct resample_data *r;
+
+ r = ctx->streams[pkt->stream_index]->codec->opaque;
+ if (r) {
+ sws_scale(r->resample_ctx, frame.data, frame.linesize, 0,
+ ctx->streams[pkt->stream_index]->codec->height,
+ r->resampled_frame.data, r->resampled_frame.linesize);
+ res = &r->resampled_frame;
+ } else {
+ res = &frame;
+ }
+
+ return res;
+ }
+
+ return NULL;
+}
+
+int codec_connect(AVCodecContext *ic, AVCodecContext *oc)
+{
+ struct resample_data *r;
+
+ if ((ic->width == oc->width) && (ic->height == oc->height) && (ic->pix_fmt == oc->pix_fmt)) {
+ return 0;
+ }
+
+ r = av_malloc(sizeof(struct resample_data));
+ r->resample_ctx = sws_getContext(ic->width, ic->height, ic->pix_fmt,
+ oc->width, oc->height, oc->pix_fmt,
+ SWS_BICUBIC, NULL, NULL, NULL);
+ if (r->resample_ctx == NULL) {
+ av_free(r);
+
+ return -1;
+ }
+ avcodec_get_frame_defaults(&r->resampled_frame);
+ avpicture_alloc((AVPicture*)&r->resampled_frame,
+ oc->pix_fmt, oc->width, oc->height);
+ ic->opaque = r;
+
+ return 1;
+}
+
+AVPacket *pkt_encode(AVFormatContext *ctx, AVFrame *frame)
+{
+ AVCodecContext *c = ctx->streams[0]->codec;
+ static AVPacket pkt;
+ int res;
+
+ if (pkt.data == NULL) {
+ pkt.size = 256 * 1024;
+ pkt.data = av_malloc(pkt.size);
+ }
+ res = avcodec_encode_video(c, pkt.data, pkt.size, frame);
+ if (c->coded_frame->pts != AV_NOPTS_VALUE) {
+ pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, ctx->streams[0]->time_base);
+ }
+ if (res < 0) {
+ return NULL;
+ }
+
+ return &pkt;
+}
+