mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
- Preliminary RTP friendly mode for H.263.
- GOB headers for H.263 coding on RTP mode. - Improved GOB header detection for H.263 decoder. Originally committed as revision 222 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
652cb0f57a
commit
644d98a4f2
@ -5,6 +5,14 @@ version 0.4.6:
|
||||
- recoded dct and motion vector search with gcc (no longer depends on
|
||||
nasm).
|
||||
- fix quantization bug in AC3 encoder.
|
||||
- added GOB header parsing on H.263/H.263+ decoder. (Juanjo)
|
||||
- bug fix on MCBPC tables of H.263. (Juanjo)
|
||||
- added Advanced Prediction Mode on H.263/H.263+ decoder. (Juanjo)
|
||||
- now we can decode H.263 streams found on QuickTime files. (Juanjo)
|
||||
- now we can decode H.263 streams found on VIVO v1 files.(Juanjo)
|
||||
- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo)
|
||||
- added GOB header for H.263/H.263+ coding on RTP mode. (Juanjo)
|
||||
- now H.263 picture size is returned on the first decoded frame. (Juanjo)
|
||||
|
||||
version 0.4.5:
|
||||
|
||||
|
@ -103,6 +103,19 @@ typedef struct AVCodecContext {
|
||||
struct AVCodec *codec;
|
||||
void *priv_data;
|
||||
|
||||
/* The following data is for RTP friendly coding */
|
||||
/* By now only H.263/H.263+ coder honours this */
|
||||
int rtp_mode; /* 1 for activate RTP friendly-mode */
|
||||
/* highers numbers represent more error-prone */
|
||||
/* enviroments, by now just "1" exist */
|
||||
|
||||
int rtp_payload_size; /* The size of the RTP payload, the coder will */
|
||||
/* do it's best to deliver a chunk with size */
|
||||
/* below rtp_payload_size, the chunk will start */
|
||||
/* with a start code on some codecs like H.263 */
|
||||
/* This doesn't take account of any particular */
|
||||
/* headers inside the transmited RTP payload */
|
||||
|
||||
/* the following fields are ignored */
|
||||
void *opaque; /* can be used to carry app specific stuff */
|
||||
char codec_name[32];
|
||||
@ -239,8 +252,8 @@ void avcodec_register_all(void);
|
||||
|
||||
#ifdef FF_POSTPROCESS
|
||||
#ifndef MBC
|
||||
#define MBC 120
|
||||
#define MBR 72
|
||||
#define MBC 48
|
||||
#define MBR 36
|
||||
#endif
|
||||
extern int quant_store[MBR+1][MBC+1]; // [Review]
|
||||
#endif
|
||||
|
@ -140,6 +140,39 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number)
|
||||
put_bits(&s->pb, 1, 0); /* no PEI */
|
||||
}
|
||||
|
||||
int h263_encode_gob_header(MpegEncContext * s, int mb_line)
|
||||
{
|
||||
int pdif=0;
|
||||
|
||||
/* Check to see if we need to put a new GBSC */
|
||||
/* for RTP packetization */
|
||||
if (s->rtp_mode) {
|
||||
pdif = s->pb.buf_ptr - s->ptr_lastgob;
|
||||
if (pdif >= s->rtp_payload_size) {
|
||||
/* Bad luck, packet must be cut before */
|
||||
align_put_bits(&s->pb);
|
||||
s->ptr_lastgob = s->pb.buf_ptr;
|
||||
put_bits(&s->pb, 17, 1); /* GBSC */
|
||||
s->gob_number = mb_line;
|
||||
put_bits(&s->pb, 5, s->gob_number); /* GN */
|
||||
put_bits(&s->pb, 2, 1); /* GFID */
|
||||
put_bits(&s->pb, 5, s->qscale); /* GQUANT */
|
||||
return pdif;
|
||||
} else if (pdif + s->mb_line_avgsize >= s->rtp_payload_size) {
|
||||
/* Cut the packet before we can't */
|
||||
align_put_bits(&s->pb);
|
||||
s->ptr_lastgob = s->pb.buf_ptr;
|
||||
put_bits(&s->pb, 17, 1); /* GBSC */
|
||||
s->gob_number = mb_line;
|
||||
put_bits(&s->pb, 5, s->gob_number); /* GN */
|
||||
put_bits(&s->pb, 2, 1); /* GFID */
|
||||
put_bits(&s->pb, 5, s->qscale); /* GQUANT */
|
||||
return pdif;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h263_encode_mb(MpegEncContext * s,
|
||||
DCTELEM block[6][64],
|
||||
int motion_x, int motion_y)
|
||||
@ -772,25 +805,18 @@ void h263_decode_init_vlc(MpegEncContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
int h263_decode_mb(MpegEncContext *s,
|
||||
DCTELEM block[6][64])
|
||||
int h263_decode_gob_header(MpegEncContext *s)
|
||||
{
|
||||
int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
|
||||
unsigned int val;
|
||||
INT16 *mot_val;
|
||||
static INT8 quant_tab[4] = { -1, -2, 1, 2 };
|
||||
unsigned int gfid;
|
||||
unsigned int val, gfid;
|
||||
|
||||
/* Check for GOB Start Code */
|
||||
if (s->mb_x == 0) {
|
||||
val = show_bits(&s->gb, 16);
|
||||
if (val == 0) {
|
||||
/* We have a GBSC probably with GSTUFF */
|
||||
skip_bits(&s->gb, 16); /* Drop the zeros */
|
||||
while (get_bits1(&s->gb) == 0); /* Seek the '1' bit */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"\nGOB Start Code at MB %d\n",
|
||||
(s->mb_y * s->mb_width) + s->mb_x);
|
||||
fprintf(stderr,"\nGOB Start Code at MB %d\n", (s->mb_y * s->mb_width) + s->mb_x);
|
||||
#endif
|
||||
s->gob_number = get_bits(&s->gb, 5); /* GN */
|
||||
gfid = get_bits(&s->gb, 2); /* GFID */
|
||||
@ -798,16 +824,19 @@ int h263_decode_mb(MpegEncContext *s,
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
/* FIXME: In the future H.263+ will have intra prediction */
|
||||
/* and we are gonna need another way to detect MPEG4 */
|
||||
if (!s->h263_pred) {
|
||||
if (s->mb_y == s->gob_number)
|
||||
s->first_gob_line = 1;
|
||||
else
|
||||
s->first_gob_line = 0;
|
||||
}
|
||||
|
||||
int h263_decode_mb(MpegEncContext *s,
|
||||
DCTELEM block[6][64])
|
||||
{
|
||||
int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
|
||||
INT16 *mot_val;
|
||||
static INT8 quant_tab[4] = { -1, -2, 1, 2 };
|
||||
|
||||
if (s->pict_type == P_TYPE) {
|
||||
if (get_bits1(&s->gb)) {
|
||||
/* skip mb */
|
||||
|
@ -140,6 +140,12 @@ static int h263_decode_frame(AVCodecContext *avctx,
|
||||
|
||||
/* decode each macroblock */
|
||||
for(s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) {
|
||||
/* Check for GOB headers on H.263 */
|
||||
/* FIXME: In the future H.263+ will have intra prediction */
|
||||
/* and we are gonna need another way to detect MPEG4 */
|
||||
if (s->mb_y && !s->h263_pred) {
|
||||
s->first_gob_line = h263_decode_gob_header(s);
|
||||
}
|
||||
for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) {
|
||||
#ifdef DEBUG
|
||||
printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
|
||||
|
@ -249,6 +249,9 @@ int MPV_encode_init(AVCodecContext *avctx)
|
||||
s->width = avctx->width;
|
||||
s->height = avctx->height;
|
||||
s->gop_size = avctx->gop_size;
|
||||
s->rtp_mode = avctx->rtp_mode;
|
||||
s->rtp_payload_size = avctx->rtp_payload_size;
|
||||
|
||||
if (s->gop_size <= 1) {
|
||||
s->intra_only = 1;
|
||||
s->gop_size = 12;
|
||||
@ -276,6 +279,8 @@ int MPV_encode_init(AVCodecContext *avctx)
|
||||
break;
|
||||
case CODEC_ID_H263P:
|
||||
s->out_format = FMT_H263;
|
||||
s->rtp_mode = 1;
|
||||
s->rtp_payload_size = 1200;
|
||||
s->h263_plus = 1;
|
||||
s->unrestricted_mv = 1;
|
||||
|
||||
@ -819,7 +824,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
|
||||
|
||||
static void encode_picture(MpegEncContext *s, int picture_number)
|
||||
{
|
||||
int mb_x, mb_y, wrap;
|
||||
int mb_x, mb_y, wrap, last_gob;
|
||||
UINT8 *ptr;
|
||||
int i, motion_x, motion_y;
|
||||
|
||||
@ -869,7 +874,29 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
||||
s->mv_type = MV_TYPE_16X16;
|
||||
s->mv_dir = MV_DIR_FORWARD;
|
||||
|
||||
/* Get the GOB height based on picture height */
|
||||
if (s->out_format == FMT_H263 && s->h263_plus) {
|
||||
if (s->height <= 400)
|
||||
s->gob_index = 1;
|
||||
else if (s->height <= 800)
|
||||
s->gob_index = 2;
|
||||
else
|
||||
s->gob_index = 4;
|
||||
}
|
||||
|
||||
for(mb_y=0; mb_y < s->mb_height; mb_y++) {
|
||||
/* Put GOB header based on RTP MTU */
|
||||
if (!mb_y) {
|
||||
s->ptr_lastgob = s->pb.buf_ptr;
|
||||
s->ptr_last_mb_line = s->pb.buf_ptr;
|
||||
} else if (s->out_format == FMT_H263 && s->h263_plus) {
|
||||
last_gob = h263_encode_gob_header(s, mb_y);
|
||||
if (last_gob) {
|
||||
//fprintf(stderr,"\nLast GOB size: %d", last_gob);
|
||||
s->first_gob_line = 1;
|
||||
} else
|
||||
s->first_gob_line = 0;
|
||||
}
|
||||
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
|
||||
|
||||
s->mb_x = mb_x;
|
||||
@ -981,7 +1008,17 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
||||
|
||||
MPV_decode_mb(s, s->block);
|
||||
}
|
||||
/* Obtain average MB line size for RTP */
|
||||
if (!mb_y)
|
||||
s->mb_line_avgsize = s->pb.buf_ptr - s->ptr_last_mb_line;
|
||||
else
|
||||
s->mb_line_avgsize = (s->mb_line_avgsize + s->pb.buf_ptr - s->ptr_last_mb_line) >> 1;
|
||||
//fprintf(stderr, "\nMB line: %d\tSize: %u\tAvg. Size: %u", s->mb_y,
|
||||
// (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize);
|
||||
s->ptr_last_mb_line = s->pb.buf_ptr;
|
||||
}
|
||||
//if (s->gob_number)
|
||||
// fprintf(stderr,"\nNumber of GOB: %d", s->gob_number);
|
||||
}
|
||||
|
||||
static int dct_quantize(MpegEncContext *s,
|
||||
|
@ -131,6 +131,7 @@ typedef struct MpegEncContext {
|
||||
|
||||
/* H.263 specific */
|
||||
int gob_number;
|
||||
int gob_index;
|
||||
int first_gob_line;
|
||||
|
||||
/* H.263+ specific */
|
||||
@ -186,6 +187,13 @@ typedef struct MpegEncContext {
|
||||
int last_qscale;
|
||||
int first_slice;
|
||||
|
||||
/* RTP specific */
|
||||
int rtp_mode;
|
||||
int rtp_payload_size;
|
||||
UINT8 *ptr_lastgob;
|
||||
UINT8 *ptr_last_mb_line;
|
||||
UINT32 mb_line_avgsize;
|
||||
|
||||
DCTELEM block[6][64] __align8;
|
||||
void (*dct_unquantize)(struct MpegEncContext *s,
|
||||
DCTELEM *block, int n, int qscale);
|
||||
@ -236,7 +244,7 @@ typedef struct RLTable {
|
||||
void init_rl(RLTable *rl);
|
||||
void init_vlc_rl(RLTable *rl);
|
||||
|
||||
static inline int get_rl_index(const RLTable *rl, int last, int run, int level)
|
||||
extern inline int get_rl_index(const RLTable *rl, int last, int run, int level)
|
||||
{
|
||||
int index;
|
||||
index = rl->index_run[last][run];
|
||||
@ -251,6 +259,7 @@ void h263_encode_mb(MpegEncContext *s,
|
||||
DCTELEM block[6][64],
|
||||
int motion_x, int motion_y);
|
||||
void h263_encode_picture_header(MpegEncContext *s, int picture_number);
|
||||
int h263_encode_gob_header(MpegEncContext * s, int mb_line);
|
||||
void h263_dc_scale(MpegEncContext *s);
|
||||
INT16 *h263_pred_motion(MpegEncContext * s, int block,
|
||||
int *px, int *py);
|
||||
@ -261,6 +270,7 @@ void h263_encode_init_vlc(MpegEncContext *s);
|
||||
|
||||
void h263_decode_init_vlc(MpegEncContext *s);
|
||||
int h263_decode_picture_header(MpegEncContext *s);
|
||||
int h263_decode_gob_header(MpegEncContext *s);
|
||||
int mpeg4_decode_picture_header(MpegEncContext * s);
|
||||
int intel_h263_decode_picture_header(MpegEncContext *s);
|
||||
int h263_decode_mb(MpegEncContext *s,
|
||||
|
Loading…
Reference in New Issue
Block a user