aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/mpeg12.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2003-12-30 16:07:57 +0000
committerMichael Niedermayer <michaelni@gmx.at>2003-12-30 16:07:57 +0000
commitbb198e198abc42753274edc376fdd15543694315 (patch)
treee263990eeb4624e54be714b7a494b7511d5dc13f /libavcodec/mpeg12.c
parentb846b231b353048693ef457285a23b0c21fc577f (diff)
downloadffmpeg-bb198e198abc42753274edc376fdd15543694315.tar.gz
interlaced motion estimation
interlaced mpeg2 encoding P & B frames rate distored interlaced mb decission alternate scantable support 4mv encoding fixes (thats also why the regression tests change) passing height to most dsp functions interlaced mpeg4 encoding (no direct mode MBs yet) various related cleanups disabled old motion estimaton algorithms (log, full, ...) they will either be fixed or removed Originally committed as revision 2638 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/mpeg12.c')
-rw-r--r--libavcodec/mpeg12.c254
1 files changed, 131 insertions, 123 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 4cc164de31..81cd9619c1 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -29,6 +29,9 @@
#include "mpeg12data.h"
+//#undef NDEBUG
+//#include <assert.h>
+
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
@@ -476,12 +479,12 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
}
static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
- int has_mv)
+ int has_mv, int field_motion)
{
put_bits(&s->pb, n, bits);
if (!s->frame_pred_frame_dct) {
if (has_mv)
- put_bits(&s->pb, 2, 2); /* motion_type: frame */
+ put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */
put_bits(&s->pb, 1, s->interlaced_dct);
}
}
@@ -501,9 +504,9 @@ void mpeg1_encode_mb(MpegEncContext *s,
if (s->block_last_index[i] >= 0)
cbp |= 1 << (5 - i);
}
-
+
if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&
- ((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) ||
+ ((s->pict_type == P_TYPE && s->mv_type == MV_TYPE_16X16 && (motion_x | motion_y) == 0) ||
(s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
s->mb_skip_run++;
@@ -511,6 +514,10 @@ void mpeg1_encode_mb(MpegEncContext *s,
s->skip_count++;
s->misc_bits++;
s->last_bits++;
+ if(s->pict_type == P_TYPE){
+ s->last_mv[0][1][0]= s->last_mv[0][0][0]=
+ s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
+ }
} else {
if(first_mb){
assert(s->mb_skip_run == 0);
@@ -521,150 +528,167 @@ void mpeg1_encode_mb(MpegEncContext *s,
if (s->pict_type == I_TYPE) {
if(s->dquant && cbp){
- put_mb_modes(s, 2, 1, 0); /* macroblock_type : macroblock_quant = 1 */
+ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */
put_bits(&s->pb, 5, s->qscale);
}else{
- put_mb_modes(s, 1, 1, 0); /* macroblock_type : macroblock_quant = 0 */
+ put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */
s->qscale -= s->dquant;
}
s->misc_bits+= get_bits_diff(s);
s->i_count++;
} else if (s->mb_intra) {
if(s->dquant && cbp){
- put_mb_modes(s, 6, 0x01, 0);
+ put_mb_modes(s, 6, 0x01, 0, 0);
put_bits(&s->pb, 5, s->qscale);
}else{
- put_mb_modes(s, 5, 0x03, 0);
+ put_mb_modes(s, 5, 0x03, 0, 0);
s->qscale -= s->dquant;
}
s->misc_bits+= get_bits_diff(s);
s->i_count++;
- s->last_mv[0][0][0] =
- s->last_mv[0][0][1] = 0;
+ memset(s->last_mv, 0, sizeof(s->last_mv));
} else if (s->pict_type == P_TYPE) {
+ if(s->mv_type == MV_TYPE_16X16){
if (cbp != 0) {
- if (motion_x == 0 && motion_y == 0) {
+ if ((motion_x|motion_y) == 0) {
if(s->dquant){
- put_mb_modes(s, 5, 1, 0); /* macroblock_pattern & quant */
+ put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */
put_bits(&s->pb, 5, s->qscale);
}else{
- put_mb_modes(s, 2, 1, 0); /* macroblock_pattern only */
+ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */
}
s->misc_bits+= get_bits_diff(s);
- put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
} else {
if(s->dquant){
- put_mb_modes(s, 5, 2, 1); /* motion + cbp */
+ put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */
put_bits(&s->pb, 5, s->qscale);
}else{
- put_mb_modes(s, 1, 1, 1); /* motion + cbp */
+ put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */
}
s->misc_bits+= get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added
s->mv_bits+= get_bits_diff(s);
- put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
}
} else {
put_bits(&s->pb, 3, 1); /* motion only */
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
+ s->misc_bits+= get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added
s->qscale -= s->dquant;
s->mv_bits+= get_bits_diff(s);
}
- s->f_count++;
- } else
- { // RAL: All the following bloc added for B frames:
- if (cbp != 0)
- { // With coded bloc pattern
- if (s->mv_dir == (MV_DIR_FORWARD | MV_DIR_BACKWARD))
- { // Bi-directional motion
- if (s->dquant) {
- put_mb_modes(s, 5, 2, 1);
- put_bits(&s->pb, 5, s->qscale);
- } else {
- put_mb_modes(s, 2, 3, 1);
- }
- s->misc_bits += get_bits_diff(s);
- mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
- mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
- mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
- mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
- s->b_count++;
- s->f_count++;
- s->mv_bits += get_bits_diff(s);
- put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
- }
- else if (s->mv_dir == MV_DIR_BACKWARD)
- { // Backward motion
- if (s->dquant) {
- put_mb_modes(s, 6, 2, 1);
- put_bits(&s->pb, 5, s->qscale);
- } else {
- put_mb_modes(s, 3, 3, 1);
- }
- s->misc_bits += get_bits_diff(s);
- mpeg1_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code);
- mpeg1_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code);
- s->b_count++;
- s->mv_bits += get_bits_diff(s);
- put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
- }
- else if (s->mv_dir == MV_DIR_FORWARD)
- { // Forward motion
- if (s->dquant) {
- put_mb_modes(s, 6, 3, 1);
- put_bits(&s->pb, 5, s->qscale);
- } else {
- put_mb_modes(s, 4, 3, 1);
- }
- s->misc_bits += get_bits_diff(s);
- mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);
- mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);
- s->f_count++;
- s->mv_bits += get_bits_diff(s);
- put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
- }
+ s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x;
+ s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y;
+ }else{
+ assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);
+
+ if (cbp) {
+ if(s->dquant){
+ put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */
+ put_bits(&s->pb, 5, s->qscale);
+ }else{
+ put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */
}
- else
- { // No coded bloc pattern
- if (s->mv_dir == (MV_DIR_FORWARD | MV_DIR_BACKWARD))
- { // Bi-directional motion
- put_bits(&s->pb, 2, 2); /* backward & forward motion */
- if (!s->frame_pred_frame_dct)
- put_bits(&s->pb, 2, 2); /* motion_type: frame */
- mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
- mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
- mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
- mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
- s->b_count++;
- s->f_count++;
- }
- else if (s->mv_dir == MV_DIR_BACKWARD)
- { // Backward motion
- put_bits(&s->pb, 3, 2); /* backward motion only */
- if (!s->frame_pred_frame_dct)
- put_bits(&s->pb, 2, 2); /* motion_type: frame */
- mpeg1_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code);
- mpeg1_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code);
- s->b_count++;
- }
- else if (s->mv_dir == MV_DIR_FORWARD)
- { // Forward motion
- put_bits(&s->pb, 4, 2); /* forward motion only */
- if (!s->frame_pred_frame_dct)
- put_bits(&s->pb, 2, 2); /* motion_type: frame */
- mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);
- mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);
- s->f_count++;
- }
+ } else {
+ put_bits(&s->pb, 3, 1); /* motion only */
+ put_bits(&s->pb, 2, 1); /* motion_type: field */
s->qscale -= s->dquant;
- s->mv_bits += get_bits_diff(s);
+ }
+ s->misc_bits+= get_bits_diff(s);
+ for(i=0; i<2; i++){
+ put_bits(&s->pb, 1, s->field_select[0][i]);
+ mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
+ mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
+ s->last_mv[0][i][0]= s->mv[0][i][0];
+ s->last_mv[0][i][1]= 2*s->mv[0][i][1];
+ }
+ s->mv_bits+= get_bits_diff(s);
+ }
+ if(cbp)
+ put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
+ s->f_count++;
+ } else{
+ static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi
+
+ if(s->mv_type == MV_TYPE_16X16){
+ if (cbp){ // With coded bloc pattern
+ if (s->dquant) {
+ if(s->mv_dir == MV_DIR_FORWARD)
+ put_mb_modes(s, 6, 3, 1, 0);
+ else
+ put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0);
+ put_bits(&s->pb, 5, s->qscale);
+ } else {
+ put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0);
+ }
+ }else{ // No coded bloc pattern
+ put_bits(&s->pb, mb_type_len[s->mv_dir], 2);
+ if (!s->frame_pred_frame_dct)
+ put_bits(&s->pb, 2, 2); /* motion_type: frame */
+ s->qscale -= s->dquant;
+ }
+ s->misc_bits += get_bits_diff(s);
+ if (s->mv_dir&MV_DIR_FORWARD){
+ mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
+ mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
+ s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0];
+ s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1];
+ s->f_count++;
+ }
+ if (s->mv_dir&MV_DIR_BACKWARD){
+ mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
+ mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
+ s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0];
+ s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1];
+ s->b_count++;
+ }
+ }else{
+ assert(s->mv_type == MV_TYPE_FIELD);
+ assert(!s->frame_pred_frame_dct);
+ if (cbp){ // With coded bloc pattern
+ if (s->dquant) {
+ if(s->mv_dir == MV_DIR_FORWARD)
+ put_mb_modes(s, 6, 3, 1, 1);
+ else
+ put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1);
+ put_bits(&s->pb, 5, s->qscale);
+ } else {
+ put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1);
}
- // End of bloc from RAL
+ }else{ // No coded bloc pattern
+ put_bits(&s->pb, mb_type_len[s->mv_dir], 2);
+ put_bits(&s->pb, 2, 1); /* motion_type: field */
+ s->qscale -= s->dquant;
+ }
+ s->misc_bits += get_bits_diff(s);
+ if (s->mv_dir&MV_DIR_FORWARD){
+ for(i=0; i<2; i++){
+ put_bits(&s->pb, 1, s->field_select[0][i]);
+ mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
+ mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
+ s->last_mv[0][i][0]= s->mv[0][i][0];
+ s->last_mv[0][i][1]= 2*s->mv[0][i][1];
+ }
+ s->f_count++;
+ }
+ if (s->mv_dir&MV_DIR_BACKWARD){
+ for(i=0; i<2; i++){
+ put_bits(&s->pb, 1, s->field_select[1][i]);
+ mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code);
+ mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code);
+ s->last_mv[1][i][0]= s->mv[1][i][0];
+ s->last_mv[1][i][1]= 2*s->mv[1][i][1];
+ }
+ s->b_count++;
+ }
}
+ s->mv_bits += get_bits_diff(s);
+ if(cbp)
+ put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
+ }
for(i=0;i<6;i++) {
if (cbp & (1 << (5 - i))) {
mpeg1_encode_block(s, block[i], i);
@@ -676,18 +700,6 @@ void mpeg1_encode_mb(MpegEncContext *s,
else
s->p_tex_bits+= get_bits_diff(s);
}
-
- // RAL: By this:
- if (s->mv_dir & MV_DIR_FORWARD)
- {
- s->last_mv[0][0][0]= s->mv[0][0][0];
- s->last_mv[0][0][1]= s->mv[0][0][1];
- }
- if (s->mv_dir & MV_DIR_BACKWARD)
- {
- s->last_mv[1][0][0]= s->mv[1][0][0];
- s->last_mv[1][0][1]= s->mv[1][0][1];
- }
}
// RAL: Parameter added: f_or_b_code
@@ -1952,7 +1964,7 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s)
s->repeat_first_field = get_bits1(&s->gb);
s->chroma_420_type = get_bits1(&s->gb);
s->progressive_frame = get_bits1(&s->gb);
-
+
if(s->picture_structure == PICT_FRAME)
s->first_field=0;
else{
@@ -1963,13 +1975,9 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s)
if(s->alternate_scan){
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
}else{
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
}
/* composite display not parsed */
@@ -2103,10 +2111,10 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
s->qscale = get_qscale(s);
if (s->first_slice && (s->first_field || s->picture_structure==PICT_FRAME)) {
if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
+ av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1],
s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")),
- s->progressive_sequence ? "pro" :"", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
+ s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
}