]> rtime.felk.cvut.cz Git - frescor/streamer.git/blob - codec.c
License
[frescor/streamer.git] / codec.c
1 /*
2  *  Copyright (c) 2008 Luca Abeni
3  *
4  *  This is free software; see GPL.txt
5  */
6 #include "libavformat/avformat.h"
7 #include "libavcodec/avcodec.h"
8 #include "libswscale/swscale.h"
9
10 struct resample_data {
11   struct SwsContext *resample_ctx;
12   int in_height;
13   AVFrame resampled_frame;
14 };
15
16 int codec_open(AVFormatContext *ctx)
17 {
18   AVCodec *codec;
19   int i, res;
20
21   for (i = 0; i < ctx->nb_streams; i++) {
22     codec = avcodec_find_decoder(ctx->streams[i]->codec->codec_id);
23     if (!codec) {
24       fprintf(stderr, "Cannot find codec %d for input stream %d\n",
25                       ctx->streams[i]->codec->codec_id, i);
26       return -1;
27     }
28     res = avcodec_open(ctx->streams[i]->codec, codec);
29     if (res < 0) {
30       fprintf(stderr, "Cannot open codec for input stream %d\n", i);
31
32       return -1;
33     }
34   }
35
36   return 0;
37 }
38
39 int out_codec_open(AVFormatContext *ctx)
40 {
41   AVCodec *codec;
42   int i, res;
43
44   for (i = 0; i < ctx->nb_streams; i++) {
45     codec = avcodec_find_encoder(ctx->streams[i]->codec->codec_id);
46     if (!codec) {
47       fprintf(stderr, "Cannot find codec %d for output stream %d\n",
48                       ctx->streams[i]->codec->codec_id, i);
49       return -1;
50     }
51     res = avcodec_open(ctx->streams[i]->codec, codec);
52     if (res < 0) {
53       fprintf(stderr, "Cannot open codec for input stream %d\n", i);
54
55       return -1;
56     }
57   }
58
59   return 0;
60 }
61
62
63 AVFrame *pkt_decode(AVFormatContext *ctx, AVPacket *pkt)
64 {
65   static AVFrame frame;
66   int res, got;
67
68   avcodec_get_frame_defaults(&frame);
69   res = avcodec_decode_video(ctx->streams[pkt->stream_index]->codec,
70         &frame, &got, pkt->data, pkt->size);
71   if (res < 0) {
72     got = res;
73   }
74
75   if (got > 0) {
76     AVFrame *res;
77     struct resample_data *r;
78
79     r = ctx->streams[pkt->stream_index]->codec->opaque;
80     if (r) {
81       sws_scale(r->resample_ctx, frame.data, frame.linesize, 0,
82                 ctx->streams[pkt->stream_index]->codec->height,
83                 r->resampled_frame.data, r->resampled_frame.linesize);
84       res = &r->resampled_frame;
85     } else {
86       res = &frame;
87     }
88
89     return res;
90   }
91
92   return NULL;
93 }
94
95 int codec_connect(AVCodecContext *ic, AVCodecContext *oc)
96 {
97   struct resample_data *r;
98
99   if ((ic->width == oc->width) && (ic->height == oc->height) && (ic->pix_fmt == oc->pix_fmt)) {
100     return 0;
101   }
102
103   r = av_malloc(sizeof(struct resample_data));
104   r->resample_ctx = sws_getContext(ic->width, ic->height, ic->pix_fmt,
105                                    oc->width, oc->height, oc->pix_fmt,
106                                    SWS_BICUBIC, NULL, NULL, NULL);
107   if (r->resample_ctx == NULL) {
108     av_free(r);
109
110     return -1;
111   }
112   avcodec_get_frame_defaults(&r->resampled_frame);
113   avpicture_alloc((AVPicture*)&r->resampled_frame,
114                   oc->pix_fmt, oc->width, oc->height);
115   ic->opaque = r;
116
117   return 1;
118 }
119
120 AVPacket *pkt_encode(AVFormatContext *ctx, AVFrame *frame)
121 {
122   AVCodecContext *c = ctx->streams[0]->codec;
123   static AVPacket pkt;
124   int res;
125
126   pkt.size = 256 * 1024;
127   if (pkt.data == NULL) {
128     pkt.data = av_malloc(pkt.size);
129   }
130   res = avcodec_encode_video(c, pkt.data, pkt.size, frame);
131   if (c->coded_frame->pts != AV_NOPTS_VALUE) {
132     pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, ctx->streams[0]->time_base);
133   }
134   if (res < 0) {
135     return NULL;
136   }
137
138   pkt.size = res;
139   return &pkt;
140 }
141