mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-19 08:11:21 +00:00
various rearrangements and renaming of console_video stuff
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@95262 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#include "asterisk/frame.h"
|
||||
|
||||
struct video_out_desc;
|
||||
struct video_in_desc;
|
||||
struct video_dec_desc;
|
||||
struct fbuf_t;
|
||||
|
||||
/*
|
||||
@@ -34,7 +34,7 @@ typedef int (*decoder_init_f)(AVCodecContext *enc_ctx);
|
||||
typedef int (*decoder_decap_f)(struct fbuf_t *b, uint8_t *data, int len);
|
||||
|
||||
/*! \brief actually call the decoder */
|
||||
typedef int (*decoder_decode_f)(struct video_in_desc *v, struct fbuf_t *b);
|
||||
typedef int (*decoder_decode_f)(struct video_dec_desc *v, struct fbuf_t *b);
|
||||
|
||||
struct video_codec_desc {
|
||||
const char *name; /* format name */
|
||||
@@ -47,6 +47,35 @@ struct video_codec_desc {
|
||||
decoder_decode_f dec_run;
|
||||
};
|
||||
|
||||
/*
|
||||
* Descriptor for the incoming stream, with multiple buffers for the bitstream
|
||||
* extracted from the RTP packets, RTP reassembly info, and a frame buffer
|
||||
* for the decoded frame (buf).
|
||||
* The descriptor is allocated as the first frame comes in.
|
||||
*
|
||||
* Incoming payload is stored in one of the dec_in[] buffers, which are
|
||||
* emptied by the video thread. These buffers are organized in a circular
|
||||
* queue, with dec_in_cur being the buffer in use by the incoming stream,
|
||||
* and dec_in_dpy is the one being displayed. When the pointers need to
|
||||
* be changed, we synchronize the access to them with dec_lock.
|
||||
* When the list is full dec_in_cur = NULL (we cannot store new data),
|
||||
* when the list is empty dec_in_dpy = NULL (we cannot display frames).
|
||||
*/
|
||||
struct video_dec_desc {
|
||||
struct video_codec_desc *d_callbacks; /* decoder callbacks */
|
||||
AVCodecContext *dec_ctx; /* information about the codec in the stream */
|
||||
AVCodec *codec; /* reference to the codec */
|
||||
AVFrame *d_frame; /* place to store the decoded frame */
|
||||
AVCodecParserContext *parser;
|
||||
uint16_t next_seq; /* must be 16 bit */
|
||||
int discard; /* flag for discard status */
|
||||
#define N_DEC_IN 3 /* number of incoming buffers */
|
||||
struct fbuf_t *dec_in_cur; /* buffer being filled in */
|
||||
struct fbuf_t *dec_in_dpy; /* buffer to display */
|
||||
struct fbuf_t dec_in[N_DEC_IN]; /* incoming bitstream, allocated/extended in fbuf_append() */
|
||||
struct fbuf_t dec_out; /* decoded frame, no buffer (data is in AVFrame) */
|
||||
};
|
||||
|
||||
#ifdef debugging_only
|
||||
|
||||
/* some debugging code to check the bitstream:
|
||||
@@ -170,6 +199,8 @@ void dump_buf(struct fbuf_t *b)
|
||||
ast_log(LOG_WARNING, "%s\n", buf);
|
||||
}
|
||||
#endif /* debugging_only */
|
||||
|
||||
|
||||
/*
|
||||
* Here starts the glue code for the various supported video codecs.
|
||||
* For each of them, we need to provide routines for initialization,
|
||||
@@ -327,7 +358,7 @@ static int ffmpeg_encode(struct video_out_desc *v)
|
||||
* proper frames. After that, if we have a valid frame, we decode it
|
||||
* until the entire frame is processed.
|
||||
*/
|
||||
static int ffmpeg_decode(struct video_in_desc *v, struct fbuf_t *b)
|
||||
static int ffmpeg_decode(struct video_dec_desc *v, struct fbuf_t *b)
|
||||
{
|
||||
uint8_t *src = b->data;
|
||||
int srclen = b->used;
|
||||
@@ -743,7 +774,7 @@ static int mpeg4_decap(struct fbuf_t *b, uint8_t *data, int len)
|
||||
return fbuf_append(b, data, len, 0, 0);
|
||||
}
|
||||
|
||||
static int mpeg4_decode(struct video_in_desc *v, struct fbuf_t *b)
|
||||
static int mpeg4_decode(struct video_dec_desc *v, struct fbuf_t *b)
|
||||
{
|
||||
int full_frame = 0, datalen = b->used;
|
||||
int ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame,
|
||||
@@ -1015,4 +1046,89 @@ static struct video_codec_desc *map_video_codec(int fmt)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! \brief uninitialize the descriptor for remote video stream */
|
||||
static struct video_dec_desc *dec_uninit(struct video_dec_desc *v)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (v->parser) {
|
||||
av_parser_close(v->parser);
|
||||
v->parser = NULL;
|
||||
}
|
||||
if (v->dec_ctx) {
|
||||
avcodec_close(v->dec_ctx);
|
||||
av_free(v->dec_ctx);
|
||||
v->dec_ctx = NULL;
|
||||
}
|
||||
if (v->d_frame) {
|
||||
av_free(v->d_frame);
|
||||
v->d_frame = NULL;
|
||||
}
|
||||
v->codec = NULL; /* only a reference */
|
||||
v->d_callbacks = NULL; /* forget the decoder */
|
||||
v->discard = 1; /* start in discard mode */
|
||||
for (i = 0; i < N_DEC_IN; i++)
|
||||
fbuf_free(&v->dec_in[i]);
|
||||
fbuf_free(&v->dec_out);
|
||||
ast_free(v);
|
||||
return NULL; /* error, in case someone cares */
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize ffmpeg resources used for decoding frames from the network.
|
||||
*/
|
||||
static struct video_dec_desc *dec_init(uint32_t the_ast_format)
|
||||
{
|
||||
enum CodecID codec;
|
||||
struct video_dec_desc *v = ast_calloc(1, sizeof(*v));
|
||||
if (v == NULL)
|
||||
return NULL;
|
||||
|
||||
v->discard = 1;
|
||||
|
||||
v->d_callbacks = map_video_codec(the_ast_format);
|
||||
if (v->d_callbacks == NULL) {
|
||||
ast_log(LOG_WARNING, "cannot find video codec, drop input 0x%x\n", the_ast_format);
|
||||
return dec_uninit(v);
|
||||
}
|
||||
|
||||
codec = map_video_format(v->d_callbacks->format, CM_RD);
|
||||
|
||||
v->codec = avcodec_find_decoder(codec);
|
||||
if (!v->codec) {
|
||||
ast_log(LOG_WARNING, "Unable to find the decoder for format %d\n", codec);
|
||||
return dec_uninit(v);
|
||||
}
|
||||
/*
|
||||
* Initialize the codec context.
|
||||
*/
|
||||
v->dec_ctx = avcodec_alloc_context();
|
||||
if (!v->dec_ctx) {
|
||||
ast_log(LOG_WARNING, "Cannot allocate the decoder context\n");
|
||||
return dec_uninit(v);
|
||||
}
|
||||
/* XXX call dec_init() ? */
|
||||
if (avcodec_open(v->dec_ctx, v->codec) < 0) {
|
||||
ast_log(LOG_WARNING, "Cannot open the decoder context\n");
|
||||
av_free(v->dec_ctx);
|
||||
v->dec_ctx = NULL;
|
||||
return dec_uninit(v);
|
||||
}
|
||||
|
||||
v->parser = av_parser_init(codec);
|
||||
if (!v->parser) {
|
||||
ast_log(LOG_WARNING, "Cannot initialize the decoder parser\n");
|
||||
return dec_uninit(v);
|
||||
}
|
||||
|
||||
v->d_frame = avcodec_alloc_frame();
|
||||
if (!v->d_frame) {
|
||||
ast_log(LOG_WARNING, "Cannot allocate decoding video frame\n");
|
||||
return dec_uninit(v);
|
||||
}
|
||||
v->dec_in_cur = &v->dec_in[0]; /* buffer for incoming frames */
|
||||
v->dec_in_dpy = NULL; /* nothing to display */
|
||||
|
||||
return v; /* ok */
|
||||
}
|
||||
/*------ end codec specific code -----*/
|
||||
|
||||
Reference in New Issue
Block a user