/*
- * MPEG1 encoder / MPEG2 decoder
+ * MPEG1 codec / MPEG2 decoder
* Copyright (c) 2000,2001 Fabrice Bellard.
*
* This library is free software; you can redistribute it and/or
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
+/**
+ * @file mpeg12.c
+ * MPEG1 codec / MPEG2 decoder.
+ */
+
//#define DEBUG
#include "avcodec.h"
#include "dsputil.h"
int i, dmin, d;
s->frame_rate_index = 0;
dmin = 0x7fffffff;
- for(i=1;i<9;i++) {
- d = abs(s->frame_rate - frame_rate_tab[i]);
+ for(i=1;i<14;i++) {
+ if(s->avctx->strict_std_compliance >= 0 && i>=9) break;
+
+ d = abs(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate/s->avctx->frame_rate_base - frame_rate_tab[i]);
if (d < dmin) {
dmin = d;
s->frame_rate_index = i;
put_bits(&s->pb, 4, s->aspect_ratio_info);
put_bits(&s->pb, 4, s->frame_rate_index);
- v = s->bit_rate / 400;
+ v = (s->bit_rate + 399) / 400;
if (v > 0x3ffff)
v = 0x3ffff;
put_bits(&s->pb, 18, v);
/* time code : we must convert from the real frame rate to a
fake mpeg frame rate in case of low frame rate */
fps = frame_rate_tab[s->frame_rate_index];
- time_code = (int64_t)s->fake_picture_number * FRAME_RATE_BASE;
+ time_code = (int64_t)s->fake_picture_number * MPEG1_FRAME_RATE_BASE;
s->gop_picture_number = s->fake_picture_number;
put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
- put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / FRAME_RATE_BASE));
+ put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / MPEG1_FRAME_RATE_BASE));
put_bits(&s->pb, 1, 1); /* closed gop */
put_bits(&s->pb, 1, 0); /* broken link */
}
- if (s->frame_rate < (24 * FRAME_RATE_BASE) && s->picture_number > 0) {
+ if (s->avctx->frame_rate < (24 * s->avctx->frame_rate_base) && s->picture_number > 0) {
/* insert empty P pictures to slow down to the desired
frame rate. Each fake pictures takes about 20 bytes */
fps = frame_rate_tab[s->frame_rate_index];
- n = (((int64_t)s->picture_number * fps) / s->frame_rate) - 1;
+ n = av_rescale((int64_t)s->picture_number * s->avctx->frame_rate_base, fps, s->avctx->frame_rate) / MPEG1_FRAME_RATE_BASE - 1;
while (s->fake_picture_number < n) {
mpeg1_skip_picture(s, s->fake_picture_number -
s->gop_picture_number);
}
break;
case MT_FIELD:
+ s->mv_type = MV_TYPE_FIELD;
if (s->picture_structure == PICT_FRAME) {
- s->mv_type = MV_TYPE_FIELD;
for(j=0;j<2;j++) {
s->field_select[i][j] = get_bits1(&s->gb);
val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
dprintf("fmy=%d\n", val);
}
} else {
- s->mv_type = MV_TYPE_16X16;
s->field_select[i][0] = get_bits1(&s->gb);
for(k=0;k<2;k++) {
val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
s->low_delay = get_bits1(&s->gb);
frame_rate_ext_n = get_bits(&s->gb, 2);
frame_rate_ext_d = get_bits(&s->gb, 5);
- if (frame_rate_ext_d >= 1)
- s->frame_rate = (s->frame_rate * frame_rate_ext_n) / frame_rate_ext_d;
+ av_reduce(
+ &s->avctx->frame_rate,
+ &s->avctx->frame_rate_base,
+ frame_rate_tab[s->frame_rate_index] * (frame_rate_ext_n+1),
+ MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d+1),
+ 1<<30);
+
dprintf("sequence extension\n");
s->mpeg2 = 1;
s->avctx->sub_id = 2; /* indicates mpeg2 found */
if (get_bits1(&s->gb)) {
for(i=0;i<64;i++) {
v = get_bits(&s->gb, 8);
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
s->intra_matrix[j] = v;
s->chroma_intra_matrix[j] = v;
}
if (get_bits1(&s->gb)) {
for(i=0;i<64;i++) {
v = get_bits(&s->gb, 8);
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
s->inter_matrix[j] = v;
s->chroma_inter_matrix[j] = v;
}
if (get_bits1(&s->gb)) {
for(i=0;i<64;i++) {
v = get_bits(&s->gb, 8);
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
s->chroma_intra_matrix[j] = v;
}
}
if (get_bits1(&s->gb)) {
for(i=0;i<64;i++) {
v = get_bits(&s->gb, 8);
- j= s->idct_permutation[ ff_zigzag_direct[i] ];
+ j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
s->chroma_inter_matrix[j] = v;
}
}
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{
+ s->first_field ^= 1;
+ memset(s->mbskip_table, 0, s->mb_width*s->mb_height);
+ }
+
if(s->alternate_scan){
ff_init_scantable(s, &s->inter_scantable , ff_alternate_vertical_scan);
ff_init_scantable(s, &s->intra_scantable , ff_alternate_vertical_scan);
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
int ret;
+ const int field_pic= s->picture_structure != PICT_FRAME;
start_code = (start_code - 1) & 0xff;
if (start_code >= s->mb_height){
s->last_dc[1] = s->last_dc[0];
s->last_dc[2] = s->last_dc[0];
memset(s->last_mv, 0, sizeof(s->last_mv));
+
/* start frame decoding */
if (s->first_slice) {
- s->first_slice = 0;
+ if(s->first_field || s->picture_structure==PICT_FRAME){
if(MPV_frame_start(s, avctx) < 0)
return DECODE_SLICE_FATAL_ERROR;
-
+ /* first check if we must repeat the frame */
+ s->current_picture.repeat_pict = 0;
+
+ if (s->repeat_first_field) {
+ if (s->progressive_sequence) {
+ if (s->top_field_first)
+ s->current_picture.repeat_pict = 4;
+ else
+ s->current_picture.repeat_pict = 2;
+ } else if (s->progressive_frame) {
+ s->current_picture.repeat_pict = 1;
+ }
+ }
+// printf("%d \n", s->current_picture.repeat_pict);
+
if(s->avctx->debug&FF_DEBUG_PICT_INFO){
printf("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",
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->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" :"");
}
+ }else{ //second field
+ int i;
+ for(i=0; i<4; i++){
+ s->current_picture.data[i] = s->current_picture_ptr->data[i];
+ if(s->picture_structure == PICT_BOTTOM_FIELD){
+ s->current_picture.data[i] += s->current_picture_ptr->linesize[i];
+ }
+ }
+ }
}
+ s->first_slice = 0;
init_get_bits(&s->gb, buf, buf_size*8);
dprintf("ret=%d\n", ret);
if (ret < 0)
return -1;
-
+
MPV_decode_mb(s, s->block);
if (++s->mb_x >= s->mb_width) {
- ff_draw_horiz_band(s);
+ if(s->picture_structure==PICT_FRAME){
+ ff_draw_horiz_band(s, 16*s->mb_y, 16);
+ }else{
+ if(!s->first_field){
+ ff_draw_horiz_band(s, 32*s->mb_y, 32);
+ }
+ }
s->mb_x = 0;
s->mb_y++;
}
}
}
- if(s->mb_y >= s->mb_height){
+ if(s->mb_y<<field_pic >= s->mb_height){
fprintf(stderr, "slice too long\n");
return DECODE_SLICE_ERROR;
}
eos: //end of slice
emms_c();
-
+//intf("%d %d %d %d\n", s->mb_y, s->mb_height, s->pict_type, s->picture_number);
/* end of slice reached */
- if (/*s->mb_x == 0 &&*/
- s->mb_y == s->mb_height) {
+ if (s->mb_y<<field_pic == s->mb_height && !s->first_field) {
/* end of image */
if(s->mpeg2)
s->picture_number++;
/* latency of 1 frame for I and P frames */
/* XXX: use another variable than picture_number */
- if (s->last_picture.data[0] == NULL) {
+ if (s->last_picture_ptr == NULL) {
return DECODE_SLICE_OK;
} else {
*pict= *(AVFrame*)&s->last_picture;
s->avctx = avctx;
avctx->width = width;
avctx->height = height;
- if (s->frame_rate_index >= 9) {
- /* at least give a valid frame rate (some old mpeg1 have this) */
- avctx->frame_rate = 25 * FRAME_RATE_BASE;
- } else {
- avctx->frame_rate = frame_rate_tab[s->frame_rate_index];
- }
- s->frame_rate = avctx->frame_rate;
+ av_reduce(
+ &avctx->frame_rate,
+ &avctx->frame_rate_base,
+ frame_rate_tab[s->frame_rate_index],
+ MPEG1_FRAME_RATE_BASE, //FIXME store in allready reduced form
+ 1<<30
+ );
avctx->bit_rate = s->bit_rate;
if (MPV_common_init(s) < 0)
#endif
} else {
for(i=0;i<64;i++) {
- int j= s->idct_permutation[i];
+ int j= s->dsp.idct_permutation[i];
v = ff_mpeg1_default_intra_matrix[i];
s->intra_matrix[j] = v;
s->chroma_intra_matrix[j] = v;
#endif
} else {
for(i=0;i<64;i++) {
- int j= s->idct_permutation[i];
+ int j= s->dsp.idct_permutation[i];
v = ff_mpeg1_default_non_intra_matrix[i];
s->inter_matrix[j] = v;
s->chroma_inter_matrix[j] = v;
return 0;
}
+static void mpeg_decode_user_data(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ const uint8_t *p;
+ int len, flags;
+ p = buf;
+ len = buf_size;
+
+ /* we parse the DTG active format information */
+ if (len >= 5 &&
+ p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
+ flags = p[4];
+ p += 5;
+ len -= 5;
+ if (flags & 0x80) {
+ /* skip event id */
+ if (len < 2)
+ return;
+ p += 2;
+ len -= 2;
+ }
+ if (flags & 0x40) {
+ if (len < 1)
+ return;
+ avctx->dtg_active_format = p[0] & 0x0f;
+ }
+ }
+}
+
/* handle buffering and image synchronisation */
static int mpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
mpeg_decode_extension(avctx,
s->buffer, input_size);
break;
+ case USER_START_CODE:
+ mpeg_decode_user_data(avctx,
+ s->buffer, input_size);
+ break;
default:
if (start_code >= SLICE_MIN_START_CODE &&
start_code <= SLICE_MAX_START_CODE) {
/* skip b frames if we dont have reference frames */
- if(s2->last_picture.data[0]==NULL && s2->pict_type==B_TYPE) break;
+ if(s2->last_picture_ptr==NULL && s2->pict_type==B_TYPE) break;
/* skip b frames if we are in a hurry */
if(avctx->hurry_up && s2->pict_type==B_TYPE) break;
/* skip everything if we are in a hurry>=5 */
ret = mpeg_decode_slice(avctx, picture,
start_code, s->buffer, input_size);
+
if (ret == DECODE_SLICE_EOP) {
- /* got a picture: exit */
- /* first check if we must repeat the frame */
- avctx->repeat_pict = 0;
-#if 0
- if (s2->progressive_frame && s2->repeat_first_field) {
- //fprintf(stderr,"\nRepeat this frame: %d! pict: %d",avctx->frame_number,s2->picture_number);
- //s2->repeat_first_field = 0;
- //s2->progressive_frame = 0;
- if (++s->repeat_field > 2)
- s->repeat_field = 0;
- avctx->repeat_pict = 1;
- }
-#endif
- if (s2->repeat_first_field) {
- if (s2->progressive_sequence) {
- if (s2->top_field_first)
- avctx->repeat_pict = 4;
- else
- avctx->repeat_pict = 2;
- } else if (s2->progressive_frame) {
- avctx->repeat_pict = 1;
- }
- }
*data_size = sizeof(AVPicture);
goto the_end;
}else if(ret<0){