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