aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuanjo <pulento@users.sourceforge.net>2001-11-19 02:13:14 +0000
committerJuanjo <pulento@users.sourceforge.net>2001-11-19 02:13:14 +0000
commit644d98a4f2f980bf95174238f1ab962dc1f692a0 (patch)
treec256c38a729e2d62a0b79a09ec8f3b159a34f920
parent652cb0f57a77ad5546ba42aebeced59e00f003df (diff)
downloadffmpeg-644d98a4f2f980bf95174238f1ab962dc1f692a0.tar.gz
- 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
-rw-r--r--Changelog8
-rw-r--r--libavcodec/avcodec.h17
-rw-r--r--libavcodec/h263.c87
-rw-r--r--libavcodec/h263dec.c6
-rw-r--r--libavcodec/mpegvideo.c39
-rw-r--r--libavcodec/mpegvideo.h14
6 files changed, 137 insertions, 34 deletions
diff --git a/Changelog b/Changelog
index 103de166f6..95422897aa 100644
--- a/Changelog
+++ b/Changelog
@@ -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:
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index b85db2d558..10d19a9c31 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -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
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 4aaf5d6ad4..3461b4f676 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -140,12 +140,45 @@ 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)
{
int cbpc, cbpy, i, cbp, pred_x, pred_y;
-
+
// printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
if (!s->mb_intra) {
/* compute cbp */
@@ -772,42 +805,38 @@ 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 */
+ 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 */
- s->qscale = get_bits(&s->gb, 5); /* GQUANT */
+ s->gob_number = get_bits(&s->gb, 5); /* GN */
+ gfid = get_bits(&s->gb, 2); /* GFID */
+ s->qscale = get_bits(&s->gb, 5); /* GQUANT */
#ifdef DEBUG
- fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale);
+ fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale);
#endif
- }
+ return 1;
}
- /* 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;
- }
+ return 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 */
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index d56bc8252b..be76e3030f 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -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);
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 148d7e142c..11ac7dcafc 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -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,
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 7b473aaa5a..e653edb9b4 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -131,6 +131,7 @@ typedef struct MpegEncContext {
/* H.263 specific */
int gob_number;
+ int gob_index;
int first_gob_line;
/* H.263+ specific */
@@ -185,7 +186,14 @@ typedef struct MpegEncContext {
int interlaced_dct;
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,