- RTP callback system implemented for H.263/H.263+.
- Bug fix on DC coefficients of H.263.
- H.263 decoder now returns PTS on picture number.
Originally committed as revision 292 to svn://svn.ffmpeg.org/ffmpeg/trunk
- 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)
+- bug fix on DC coefficients 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)
/* 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 RTP callcack: This function is called */
+ /* every time the encoder as a packet to send */
+ /* Depends on the encoder if the data starts */
+ /* with a Start Code (it should) H.263 does */
+ void (*rtp_callback)(void *data, int size, int packet_number);
+
/* the following fields are ignored */
void *opaque; /* can be used to carry app specific stuff */
int format;
align_put_bits(&s->pb);
- put_bits(&s->pb, 22, 0x20);
+
+ /* Update the pointer to last GOB */
+ s->ptr_lastgob = s->pb.buf_ptr;
+ s->gob_number = 0;
+
+ put_bits(&s->pb, 22, 0x20); /* PSC */
put_bits(&s->pb, 8, ((s->picture_number * 30 * FRAME_RATE_BASE) /
s->frame_rate) & 0xff);
if (pdif >= s->rtp_payload_size) {
/* Bad luck, packet must be cut before */
align_put_bits(&s->pb);
+ flush_put_bits(&s->pb);
+ /* Call the RTP callback to send the last GOB */
+ if (s->rtp_callback) {
+ pdif = s->pb.buf_ptr - s->ptr_lastgob;
+ s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number);
+ }
s->ptr_lastgob = s->pb.buf_ptr;
put_bits(&s->pb, 17, 1); /* GBSC */
- s->gob_number = mb_line;
+ s->gob_number = mb_line / s->gob_index;
put_bits(&s->pb, 5, s->gob_number); /* GN */
- put_bits(&s->pb, 2, 1); /* GFID */
+ put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */
put_bits(&s->pb, 5, s->qscale); /* GQUANT */
+ //fprintf(stderr,"\nGOB: %2d size: %d", s->gob_number - 1, pdif);
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);
+ flush_put_bits(&s->pb);
+ /* Call the RTP callback to send the last GOB */
+ if (s->rtp_callback) {
+ pdif = s->pb.buf_ptr - s->ptr_lastgob;
+ s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number);
+ }
s->ptr_lastgob = s->pb.buf_ptr;
put_bits(&s->pb, 17, 1); /* GBSC */
- s->gob_number = mb_line;
+ s->gob_number = mb_line / s->gob_index;
put_bits(&s->pb, 5, s->gob_number); /* GN */
- put_bits(&s->pb, 2, 1); /* GFID */
+ put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */
put_bits(&s->pb, 5, s->qscale); /* GQUANT */
+ //fprintf(stderr,"\nGOB: %2d size: %d", s->gob_number - 1, pdif);
return pdif;
}
}
RLTable *rl = &rl_inter;
if (s->mb_intra) {
- /* DC coef */
- level = block[0];
+ /* DC coef */
+ level = block[0];
/* 255 cannot be represented, so we clamp */
if (level > 254) {
level = 254;
block[0] = 254;
}
- if (level == 128)
- put_bits(&s->pb, 8, 0xff);
- else
- put_bits(&s->pb, 8, level & 0xff);
- i = 1;
+ /* 0 cannot be represented also */
+ else if (!level) {
+ level = 1;
+ block[0] = 1;
+ }
+ if (level == 128)
+ put_bits(&s->pb, 8, 0xff);
+ else
+ put_bits(&s->pb, 8, level & 0xff);
+ i = 1;
} else {
- i = 0;
+ i = 0;
}
/* AC coefs */
/* picture header */
if (get_bits(&s->gb, 22) != 0x20)
return -1;
- skip_bits(&s->gb, 8); /* picture timestamp */
-
+ s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */
+
if (get_bits1(&s->gb) != 1)
return -1; /* marker */
if (get_bits1(&s->gb) != 0)
pict->linesize[2] = s->linesize / 2;
avctx->quality = s->qscale;
+
+ /* Return the Picture timestamp as the frame number */
+ /* we substract 1 because it is added on utils.c */
+ avctx->frame_number = s->picture_number - 1;
+
*data_size = sizeof(AVPicture);
return buf_size;
}
s->gop_size = avctx->gop_size;
s->rtp_mode = avctx->rtp_mode;
s->rtp_payload_size = avctx->rtp_payload_size;
+ if (avctx->rtp_callback)
+ s->rtp_callback = avctx->rtp_callback;
s->avctx = avctx;
if (s->gop_size <= 1) {
static void encode_picture(MpegEncContext *s, int picture_number)
{
- int mb_x, mb_y, wrap, last_gob;
+ int mb_x, mb_y, wrap, last_gob, pdif = 0;
UINT8 *ptr;
int i, motion_x, motion_y;
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->out_format == FMT_H263 && !s->h263_pred && !s->h263_msmpeg4) {
if (s->height <= 400)
s->gob_index = 1;
else if (s->height <= 800)
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;
+ /* TODO: Put all this stuff in a separate generic function */
+ if (s->rtp_mode) {
+ if (!mb_y) {
+ s->ptr_lastgob = s->pb.buf;
+ s->ptr_last_mb_line = s->pb.buf;
+ } else if (s->out_format == FMT_H263 && !s->h263_pred && !s->h263_msmpeg4 && !(mb_y % s->gob_index)) {
+ last_gob = h263_encode_gob_header(s, mb_y);
+ if (last_gob) {
+ s->first_gob_line = 1;
+ }
+ }
}
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
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;
+ /* Obtain average GOB size for RTP */
+ if (s->rtp_mode) {
+ if (!mb_y)
+ s->mb_line_avgsize = s->pb.buf_ptr - s->ptr_last_mb_line;
+ else if (!(mb_y % s->gob_index)) {
+ s->mb_line_avgsize = (s->mb_line_avgsize + s->pb.buf_ptr - s->ptr_last_mb_line) >> 1;
+ s->ptr_last_mb_line = s->pb.buf_ptr;
+ }
+ //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->first_gob_line = 0;
+ }
}
if (s->h263_msmpeg4)
//if (s->gob_number)
// fprintf(stderr,"\nNumber of GOB: %d", s->gob_number);
+
+ /* Send the last GOB if RTP */
+ if (s->rtp_mode) {
+ flush_put_bits(&s->pb);
+ pdif = s->pb.buf_ptr - s->ptr_lastgob;
+ /* Call the RTP callback to send the last GOB */
+ if (s->rtp_callback)
+ s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number);
+ s->ptr_lastgob = s->pb.buf_ptr;
+ //fprintf(stderr,"\nGOB: %2d size: %d (last)", s->gob_number, pdif);
+ }
+
}
static int dct_quantize_c(MpegEncContext *s,
int first_slice;
/* RTP specific */
+ /* These are explained on avcodec.h */
int rtp_mode;
int rtp_payload_size;
+ void (*rtp_callback)(void *data, int size, int packet_number);
UINT8 *ptr_lastgob;
UINT8 *ptr_last_mb_line;
UINT32 mb_line_avgsize;