]> git.vomp.tv Git - vompclient.git/blob - raspi-patches/libav_transcode.patch
Fix text corruption in channel number display on live tv
[vompclient.git] / raspi-patches / libav_transcode.patch
1 From a1960a00ad4c6f67917f5f4bfcbf739634958dd6 Mon Sep 17 00:00:00 2001
2 From: Marten Richter <marten.richter@freenet.de>
3 Date: Sun, 19 Aug 2012 13:58:58 +0200
4 Subject: [PATCH] Add transcoding Mpeg2 to Mpeg4 code initial revision
5
6 ---
7  libavcodec/Makefile              |    2 +
8  libavcodec/allcodecs.c           |    1 +
9  libavcodec/avcodec.h             |    5 +
10  libavcodec/mpeg12.c              |   82 +++-
11  libavcodec/mpeg4video.h          |    5 +
12  libavcodec/mpeg4videodec.c       |    2 +-
13  libavcodec/mpeg4videoenc.c       |   32 +-
14  libavcodec/mpegvideo.c           |   16 +-
15  libavcodec/mpegvideo.h           |    6 +
16  libavcodec/mpegvideo_enc.c       |    8 +-
17  libavcodec/mpegvideo_transcode.c |  888 ++++++++++++++++++++++++++++++++++++++
18  libavcodec/transcode.h           |   69 +++
19  libavcodec/transcode_internal.h  |   34 ++
20  libavutil/pixfmt.h               |    2 +
21  14 files changed, 1138 insertions(+), 14 deletions(-)
22  create mode 100644 libavcodec/mpegvideo_transcode.c
23  create mode 100644 libavcodec/transcode.h
24  create mode 100644 libavcodec/transcode_internal.h
25
26 diff --git a/libavcodec/Makefile b/libavcodec/Makefile
27 index 77126a6..46f1efc 100644
28 --- a/libavcodec/Makefile
29 +++ b/libavcodec/Makefile
30 @@ -9,6 +9,7 @@ HEADERS = avcodec.h                                                     \
31            vdpau.h                                                       \
32            version.h                                                     \
33            xvmc.h                                                        \
34 +          transcode.h                                             \
35  
36  OBJS = allcodecs.o                                                      \
37         audioconvert.o                                                   \
38 @@ -264,6 +265,7 @@ OBJS-$(CONFIG_MPC7_DECODER)            += mpc7.o mpc.o mpegaudiodec.o      \
39  OBJS-$(CONFIG_MPC8_DECODER)            += mpc8.o mpc.o mpegaudiodec.o      \
40                                            mpegaudiodecheader.o mpegaudio.o \
41                                            mpegaudiodata.o
42 +OBJS-$(CONFIG_MPEG_MPEG4_DECODER)       += mpegvideo_transcode.o
43  OBJS-$(CONFIG_MPEG_XVMC_DECODER)       += mpegvideo_xvmc.o
44  OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12.o mpeg12data.o \
45                                            mpegvideo.o error_resilience.o
46 diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
47 index cb08e33..00fc162 100644
48 --- a/libavcodec/allcodecs.c
49 +++ b/libavcodec/allcodecs.c
50 @@ -146,6 +146,7 @@ void avcodec_register_all(void)
51      REGISTER_DECODER (MMVIDEO, mmvideo);
52      REGISTER_DECODER (MOTIONPIXELS, motionpixels);
53      REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc);
54 +    REGISTER_DECODER (MPEG_MPEG4, mpeg_mpeg4);
55      REGISTER_ENCDEC  (MPEG1VIDEO, mpeg1video);
56      REGISTER_ENCDEC  (MPEG2VIDEO, mpeg2video);
57      REGISTER_ENCDEC  (MPEG4, mpeg4);
58 diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
59 index 2b70b96..0cbd733 100644
60 --- a/libavcodec/avcodec.h
61 +++ b/libavcodec/avcodec.h
62 @@ -257,6 +257,7 @@ enum CodecID {
63      CODEC_ID_ZEROCODEC,
64      CODEC_ID_MSS1,
65      CODEC_ID_MSA1,
66 +    CODEC_ID_MPEG2VIDEO_MPEG4,
67  
68      /* various PCM "codecs" */
69      CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
70 @@ -696,6 +697,10 @@ typedef struct RcOverride{
71   * Audio encoder supports receiving a different number of samples in each call.
72   */
73  #define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000
74 +/**
75 + * Codec can export data for transcoding (AV).
76 + */
77 +#define CODEC_CAP_HWACCEL_TRANSCODE    0x20000
78  
79  //The following defines may change, don't expect compatibility if you use them.
80  #define MB_TYPE_INTRA4x4   0x0001
81 diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
82 index c40649d..01133e5 100644
83 --- a/libavcodec/mpeg12.c
84 +++ b/libavcodec/mpeg12.c
85 @@ -37,6 +37,7 @@
86  #include "bytestream.h"
87  #include "vdpau_internal.h"
88  #include "xvmc_internal.h"
89 +#include "transcode_internal.h"
90  #include "thread.h"
91  
92  //#undef NDEBUG
93 @@ -1183,6 +1184,8 @@ static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
94  
95      if (avctx->xvmc_acceleration)
96          return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420);
97 +    else if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE)
98 +       return PIX_FMT_TRANSCODE;
99      else if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
100          if (avctx->codec_id == CODEC_ID_MPEG1VIDEO)
101              return PIX_FMT_VDPAU_MPEG1;
102 @@ -1289,7 +1292,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
103          // until then pix_fmt may be changed right after codec init
104          if (avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
105              avctx->hwaccel                            ||
106 -            s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
107 +            s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU ||
108 +            s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE)
109              if (avctx->idct_algo == FF_IDCT_AUTO)
110                  avctx->idct_algo = FF_IDCT_SIMPLE;
111  
112 @@ -1305,8 +1309,14 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
113          quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->dsp.idct_permutation);
114          quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->dsp.idct_permutation);
115  
116 +        if (CONFIG_MPEG_MPEG4_DECODER && s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE) {
117 +           if (ff_mpeg_transcode_decode_postinit(avctx)<0)
118 +               return -2;
119 +        }
120          s1->mpeg_enc_ctx_allocated = 1;
121      }
122 +
123 +
124      return 0;
125  }
126  
127 @@ -1916,7 +1926,8 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
128  
129          ff_MPV_frame_end(s);
130  
131 -        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
132 +        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay 
133 +              || (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE)) {//no reordering for transcoding
134              *pict = s->current_picture_ptr->f;
135              ff_print_debug_info(s, pict);
136          } else {
137 @@ -2034,7 +2045,8 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
138      avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
139  
140      if (avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ||
141 -        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
142 +        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU ||
143 +        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE)
144          if (avctx->idct_algo == FF_IDCT_AUTO)
145              avctx->idct_algo = FF_IDCT_SIMPLE;
146  
147 @@ -2262,7 +2274,8 @@ static int decode_chunks(AVCodecContext *avctx,
148                      ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
149  
150                  if (slice_end(avctx, picture)) {
151 -                    if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
152 +                    if (s2->last_picture_ptr || s2->low_delay ||
153 +                        (avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE) ) //FIXME merge with the stuff in mpeg_decode_slice
154                          *data_size = sizeof(AVPicture);
155                  }
156              }
157 @@ -2528,6 +2541,67 @@ AVCodec ff_mpeg2video_decoder = {
158      .profiles       = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
159  };
160  
161 +#if CONFIG_MPEG_MPEG4_DECODER
162 +
163 +static av_cold int mpeg_transcode_decode_init(AVCodecContext *avctx)
164 +{
165 +    Mpeg1Context *s = avctx->priv_data;
166 +    MpegEncContext *s2;
167 +    
168 +
169 +    if (avctx->active_thread_type & FF_THREAD_SLICE)
170 +        return -1;
171 +    if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
172 +        return -1;
173 +    mpeg_decode_init(avctx);
174 +
175 +    avctx->pix_fmt = PIX_FMT_TRANSCODE;
176 +
177 +    s->mpeg_enc_ctx.transcode_context = (void*) av_mallocz(sizeof(MpegEncContext));
178 +    if (!s->mpeg_enc_ctx.transcode_context) {
179 +       return AVERROR(ENOMEM);
180 +    }
181 +    s2=(MpegEncContext*)s->mpeg_enc_ctx.transcode_context;
182 +    s2->current_picture_ptr =&s2->current_picture;
183 +   
184 +
185 +    
186 +    s->mpeg_enc_ctx.transcode = 1;
187 +
188 +    return 0;
189 +}
190 +
191 +static int mpeg_transcode_decode_end(AVCodecContext *avctx)
192 +{
193 +    MpegEncContext *s2;
194 +    Mpeg1Context *s = avctx->priv_data;
195 +    s2=(MpegEncContext*)s->mpeg_enc_ctx.transcode_context;
196 +    
197 +    if (s2->current_picture_ptr)
198 +        ff_free_picture(s2,&s2->current_picture);
199 +    if (s2)    
200 +        av_free(s2);
201 +        
202 +    return mpeg_decode_end(avctx);
203 +}
204 +
205 +
206 +AVCodec ff_mpeg_mpeg4_decoder = {
207 +    .name           = "mpegvideo_mpeg4",
208 +    .type           = AVMEDIA_TYPE_VIDEO,
209 +    .id             = CODEC_ID_MPEG2VIDEO_MPEG4,
210 +    .priv_data_size = sizeof(Mpeg1Context),
211 +    .init           = mpeg_transcode_decode_init,
212 +    .close          = mpeg_transcode_decode_end,
213 +    .decode         = mpeg_decode_frame,
214 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL_TRANSCODE | CODEC_CAP_DELAY,
215 +    .flush          = flush,
216 +    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-1/2 video to MPEG-4 part 2 transcoder for hardware accelaration"),
217 +};
218 +
219 +#endif
220 +
221 +
222  #if CONFIG_MPEG_XVMC_DECODER
223  static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
224  {
225 diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
226 index 64c0243..a8963df 100644
227 --- a/libavcodec/mpeg4video.h
228 +++ b/libavcodec/mpeg4video.h
229 @@ -88,6 +88,7 @@ void ff_mpeg4_encode_mb(MpegEncContext *s,
230  void ff_mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
231                        int dir);
232  void ff_set_mpeg4_time(MpegEncContext * s);
233 +void ff_set_frame_distances(MpegEncContext * s);
234  void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
235  
236  int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb);
237 @@ -102,6 +103,10 @@ int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
238  int ff_mpeg4_decode_video_packet_header(MpegEncContext *s);
239  void ff_mpeg4_init_direct_mv(MpegEncContext *s);
240  
241 +#if CONFIG_MPEG_MPEG4_DECODER
242 +void ff_mpeg4_transcode_init_tables(MpegEncContext* s);
243 +#endif
244 +
245  /**
246   *
247   * @return the mb_type
248 diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
249 index 3fcc6d0..d588f57 100644
250 --- a/libavcodec/mpeg4videodec.c
251 +++ b/libavcodec/mpeg4videodec.c
252 @@ -863,7 +863,7 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
253              dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<<n)&32;
254          }else{
255              level = mpeg4_decode_dc(s, n, &dc_pred_dir);
256 -            if (level < 0)
257 +            if (level < 0) 
258                  return -1;
259          }
260          block[0] = level;
261 diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
262 index 95bb3a5..a0dd6b2 100644
263 --- a/libavcodec/mpeg4videoenc.c
264 +++ b/libavcodec/mpeg4videoenc.c
265 @@ -499,7 +499,8 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
266              assert(mb_type>=0);
267  
268              /* nothing to do if this MB was skipped in the next P Frame */
269 -            if (s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ...
270 +            if (!(CONFIG_MPEG_MPEG4_DECODER && s->transcode) &&
271 +                  s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ...
272                  s->skip_count++;
273                  s->mv[0][0][0]=
274                  s->mv[0][0][1]=
275 @@ -614,10 +615,11 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
276                  s->p_tex_bits+= get_bits_diff(s);
277              }
278  
279 -        }else{ /* s->pict_type==AV_PICTURE_TYPE_B */
280 +        }else{ /* s->pict_type==AV_PICTURE_TYPE_P */
281              cbp= get_p_cbp(s, block, motion_x, motion_y);
282  
283 -            if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) {
284 +            if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16
285 +                 && !(CONFIG_MPEG_MPEG4_DECODER && s->transcode) ) {
286                  /* check if the B frames can skip it too, as we must skip it if we skip here
287                     why didn't they just compress the skip-mb bits instead of reusing them ?! */
288                  if(s->max_b_frames>0){
289 @@ -860,6 +862,8 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){
290      time = s->current_picture_ptr->f.pts;
291      if(s->reordered_input_picture[1])
292          time = FFMIN(time, s->reordered_input_picture[1]->f.pts);
293 +    if (CONFIG_MPEG_MPEG4_DECODER && s->transcode)
294 +        time = FFMIN(time, s->last_picture.f.pts);
295      time= time*s->avctx->time_base.num;
296  
297      seconds= time/s->avctx->time_base.den;
298 @@ -1263,6 +1267,28 @@ static av_cold int encode_init(AVCodecContext *avctx)
299      return 0;
300  }
301  
302 +#if CONFIG_MPEG_MPEG4_DECODER
303 +
304 +void ff_mpeg4_transcode_init_tables(MpegEncContext* s)
305 +{
306 +     init_uni_dc_tab();
307 +     ff_init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]);
308 +     init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len);
309 +     init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
310 +     s->min_qcoeff= -2048;
311 +     s->max_qcoeff=  2047;
312 +     s->inter_ac_vlc_length     = uni_mpeg4_inter_rl_len;
313 +     s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64;
314 +     s->luma_dc_vlc_length= uni_DCtab_lum_len;
315 +     s->ac_esc_length= 7+2+1+6+1+12+1;
316 +     s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
317 +     s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
318 +     
319 +     
320 +}
321 +
322 +#endif
323 +
324  void ff_mpeg4_init_partitions(MpegEncContext *s)
325  {
326      uint8_t *start= put_bits_ptr(&s->pb);
327 diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
328 index 574893e..8f25689 100644
329 --- a/libavcodec/mpegvideo.c
330 +++ b/libavcodec/mpegvideo.c
331 @@ -38,6 +38,7 @@
332  #include "msmpeg4.h"
333  #include "faandct.h"
334  #include "xvmc_internal.h"
335 +#include "transcode_internal.h"
336  #include "thread.h"
337  #include <limits.h>
338  
339 @@ -379,7 +380,7 @@ fail: // for  the FF_ALLOCZ_OR_GOTO macro
340  /**
341   * Deallocate a picture.
342   */
343 -static void free_picture(MpegEncContext *s, Picture *pic)
344 +void ff_free_picture(MpegEncContext *s, Picture *pic)
345  {
346      int i;
347  
348 @@ -996,7 +997,7 @@ void ff_MPV_common_end(MpegEncContext *s)
349  
350      if (s->picture && !s->avctx->internal->is_copy) {
351          for (i = 0; i < s->picture_count; i++) {
352 -            free_picture(s, &s->picture[i]);
353 +            ff_free_picture(s, &s->picture[i]);
354          }
355      }
356      av_freep(&s->picture);
357 @@ -1353,6 +1354,9 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
358  
359      if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
360          return ff_xvmc_field_start(s, avctx);
361 +    if (CONFIG_MPEG_MPEG4_DECODER && 
362 +          s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE)
363 +        return ff_transcode_start_picture(s, avctx);
364  
365      return 0;
366  }
367 @@ -1366,6 +1370,9 @@ void ff_MPV_frame_end(MpegEncContext *s)
368      // just to make sure that all data is rendered.
369      if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) {
370          ff_xvmc_field_end(s);
371 +    } else if (CONFIG_MPEG_MPEG4_DECODER && 
372 +          s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE) {
373 +       ff_transcode_end_picture(s);
374     } else if ((s->error_count || s->encoding) &&
375                !s->avctx->hwaccel &&
376                !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
377 @@ -1941,6 +1948,11 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
378          ff_xvmc_decode_mb(s);//xvmc uses pblocks
379          return;
380      }
381 +    if ( CONFIG_MPEG_MPEG4_DECODER &&
382 +               s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_TRANSCODE){
383 +       ff_transcode_decode_mb(s); //transcode does no real decoding
384 +       return;
385 +    }
386  
387      if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
388         /* save DCT coefficients */
389 diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
390 index f5b20e6..8d37178 100644
391 --- a/libavcodec/mpegvideo.h
392 +++ b/libavcodec/mpegvideo.h
393 @@ -702,6 +702,9 @@ typedef struct MpegEncContext {
394  
395      /* temp buffers for rate control */
396      float *cplx_tab, *bits_tab;
397 +    /*  transcode, encoding context: a pointer to another MpegEncContext*/
398 +    void *transcode_context;
399 +    int transcode; // 0 no transcoding, 1 activated
400  } MpegEncContext;
401  
402  #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
403 @@ -745,6 +748,7 @@ void ff_MPV_common_end(MpegEncContext *s);
404  void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]);
405  int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx);
406  void ff_MPV_frame_end(MpegEncContext *s);
407 +void ff_MPV_encode_defaults(MpegEncContext *s);
408  int ff_MPV_encode_init(AVCodecContext *avctx);
409  int ff_MPV_encode_end(AVCodecContext *avctx);
410  int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
411 @@ -787,6 +791,8 @@ void ff_copy_picture(Picture *dst, Picture *src);
412   */
413  int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared);
414  
415 +void ff_free_picture(MpegEncContext *s, Picture *pic);
416 +
417  extern const enum PixelFormat ff_pixfmt_list_420[];
418  extern const enum PixelFormat ff_hwaccel_pixfmt_list_420[];
419  
420 diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
421 index f88df92..a35c292 100644
422 --- a/libavcodec/mpegvideo_enc.c
423 +++ b/libavcodec/mpegvideo_enc.c
424 @@ -256,7 +256,7 @@ static void update_duplicate_context_after_me(MpegEncContext *dst,
425   * Set the given MpegEncContext to defaults for encoding.
426   * the changed fields will not depend upon the prior state of the MpegEncContext.
427   */
428 -static void MPV_encode_defaults(MpegEncContext *s)
429 +void ff_MPV_encode_defaults(MpegEncContext *s)
430  {
431      int i;
432      ff_MPV_common_defaults(s);
433 @@ -275,7 +275,7 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
434      int i;
435      int chroma_h_shift, chroma_v_shift;
436  
437 -    MPV_encode_defaults(s);
438 +    ff_MPV_encode_defaults(s);
439  
440      switch (avctx->codec_id) {
441      case CODEC_ID_MPEG2VIDEO:
442 @@ -3085,7 +3085,7 @@ static int estimate_qp(MpegEncContext *s, int dry_run){
443  }
444  
445  /* must be called before writing the header */
446 -static void set_frame_distances(MpegEncContext * s){
447 +void ff_set_frame_distances(MpegEncContext * s){
448      assert(s->current_picture_ptr->f.pts != AV_NOPTS_VALUE);
449      s->time = s->current_picture_ptr->f.pts * s->avctx->time_base.num;
450  
451 @@ -3114,7 +3114,7 @@ static int encode_picture(MpegEncContext *s, int picture_number)
452      /* we need to initialize some time vars before we can encode b-frames */
453      // RAL: Condition added for MPEG1VIDEO
454      if (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || (s->h263_pred && !s->msmpeg4_version))
455 -        set_frame_distances(s);
456 +        ff_set_frame_distances(s);
457      if(CONFIG_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4)
458          ff_set_mpeg4_time(s);
459  
460 diff --git a/libavcodec/mpegvideo_transcode.c b/libavcodec/mpegvideo_transcode.c
461 new file mode 100644
462 index 0000000..e2e56e1
463 --- /dev/null
464 +++ b/libavcodec/mpegvideo_transcode.c
465 @@ -0,0 +1,888 @@
466 +/*
467 + * Transcoder
468 + * Copyright (c) 2012 Marten Richter
469 + *
470 + * For the code took from the encoder:
471 + * Copyright (c) 2000,2001 Fabrice Bellard
472 + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
473 + * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
474 + * and probably many others see the git commit notes for details
475 + *
476 + * This file is part of Libav.
477 + *
478 + * Libav is free software; you can redistribute it and/or
479 + * modify it under the terms of the GNU Lesser General Public
480 + * License as published by the Free Software Foundation; either
481 + * version 2.1 of the License, or (at your option) any later version.
482 + *
483 + * Libav is distributed in the hope that it will be useful,
484 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
485 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
486 + * Lesser General Public License for more details.
487 + *
488 + * You should have received a copy of the GNU Lesser General Public
489 + * License along with Libav; if not, write to the Free Software
490 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
491 + */
492 +
493 +#include "avcodec.h"
494 +#include "dsputil.h"
495 +#include "mpegvideo.h"
496 +#include "mpegvideo_common.h"
497 +#include "mpeg4video.h"
498 +
499 +#include "mpeg12.h"
500 +#include "h263.h"
501 +
502 +#undef NDEBUG
503 +#include <assert.h>
504 +
505 +#include "transcode.h"
506 +#include "transcode_internal.h"
507 +
508 +int transcode_qmul_table[32];
509 +
510 +/**
511 + * initialise the encoding contexts, after the properties of the incoming stream are known
512 + *  TODO: remove unnecessary inits
513 + */
514 +int ff_mpeg_transcode_decode_postinit(AVCodecContext* avctx)
515 +{
516 +       // Now init the encode context
517 +       Mpeg1Context *s2;
518 +       MpegEncContext *s;
519 +       int i;
520 +       int chroma_h_shift, chroma_v_shift;
521 +       int savetimebaseden;
522 +
523 +
524 +       s2 = avctx->priv_data;
525 +       s = s2->mpeg_enc_ctx.transcode_context;
526 +
527 +       ff_MPV_encode_defaults(s);
528 +       s->codec_id=CODEC_ID_MPEG4;
529 +
530 +       s->input_picture_number = 0;
531 +       s->transcode = 1;
532 +       avctx->qmin = 1;
533 +
534 +
535 +       s->bit_rate = avctx->bit_rate;
536 +       s->width    = avctx->width+32;
537 +       s->height   = avctx->height;
538 +       s->gop_size     = avctx->gop_size;
539 +       s->avctx        = avctx;
540 +       s->flags        = avctx->flags;
541 +       s->flags2       = avctx->flags2;
542 +       s->max_b_frames = 100; // we have b frames
543 +       //s->codec_id     = avctx->codec->id;
544 +       s->strict_std_compliance = avctx->strict_std_compliance;
545 +       s->quarter_sample     = 0;
546 +       s->mpeg_quant         = 0;
547 +       s->rtp_mode           = 0; //we need it for qscale
548 +       s->vol_sprite_usage=0;
549 +       s->intra_dc_precision = avctx->intra_dc_precision;
550 +       s->user_specified_pts = AV_NOPTS_VALUE;
551 +
552 +       if (s->gop_size <= 1) {
553 +               s->intra_only = 1;
554 +               s->gop_size   = 12;
555 +       } else {
556 +               s->intra_only = 0;
557 +       }
558 +
559 +       s->me_method = avctx->me_method;
560 +       s->adaptive_quant = (s->avctx->lumi_masking ||
561 +                       s->avctx->dark_masking ||
562 +                       s->avctx->temporal_cplx_masking ||
563 +                       s->avctx->spatial_cplx_masking  ||
564 +                       s->avctx->p_masking      ||
565 +                       s->avctx->border_masking ||
566 +                       (s->mpv_flags & FF_MPV_FLAG_QP_RD)) &&
567 +                       !s->fixed_qscale;
568 +       s->loop_filter      = 0; //no loop for mpeg4
569 +
570 +       if (s->mpeg_quant || s->codec_id == CODEC_ID_MPEG1VIDEO ||
571 +                       s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG) {
572 +               // (a + x * 3 / 8) / x
573 +               s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3);
574 +               s->inter_quant_bias = 0;
575 +       } else {
576 +               s->intra_quant_bias = 0;
577 +               // (a - x / 4) / x
578 +               s->inter_quant_bias = -(1 << (QUANT_BIAS_SHIFT - 2));
579 +       }
580 +
581 +       avcodec_get_chroma_sub_sample(PIX_FMT_YUV422P, &chroma_h_shift,
582 +                       &chroma_v_shift);
583 +       if (/*avctx->codec_id == CODEC_ID_MPEG4 &&*/
584 +                       s->avctx->time_base.den > (1 << 16) - 1)
585 +       {
586 +               av_log(avctx, AV_LOG_ERROR,
587 +                               "timebase %d/%d not supported by MPEG 4 standard, "
588 +                               "the maximum admitted value for the timebase denominator "
589 +                               "is %d\n", s->avctx->time_base.num, s->avctx->time_base.den,
590 +                               (1 << 16) - 1);
591 +               return -1;
592 +       }
593 +       s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
594 +
595 +       // mpeg4 paramter
596 +       s->out_format      = FMT_H263;
597 +       s->h263_pred       = 1;
598 +       s->unrestricted_mv = 1; //does not really matter
599 +       s->low_delay       = s->max_b_frames ? 0 : 1;
600 +       avctx->delay       = s->low_delay ? 0 : (s->max_b_frames + 1);
601 +       avctx->has_b_frames = !s->low_delay;
602 +
603 +       s->encoding = 1;
604 +       s->progressive_frame    =
605 +                       s->progressive_sequence = !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT |
606 +                                       CODEC_FLAG_INTERLACED_ME) ||
607 +                                       s->alternate_scan);
608 +       /* init */
609 +       if (ff_MPV_common_init(s) < 0)
610 +               return -1;
611 +
612 +       if (!s->dct_quantize)
613 +               s->dct_quantize = ff_dct_quantize_c;
614 +       /*  if (!s->denoise_dct)
615 +        s->denoise_dct  = denoise_dct_c;
616 +     s->fast_dct_quantize = s->dct_quantize;
617 +     if (avctx->trellis)
618 +        s->dct_quantize  = dct_quantize_trellis_c;*/
619 +
620 +
621 +       s->quant_precision = 5;
622 +
623 +       ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);
624 +       ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp);
625 +
626 +       if (CONFIG_H263_ENCODER && s->out_format == FMT_H263)
627 +               ff_h263_encode_init(s);
628 +
629 +       /* init q matrix */
630 +       for (i = 0; i < 64; i++) {
631 +               int j = s->dsp.idct_permutation[i];
632 +               int j2 = s2->mpeg_enc_ctx.dsp.idct_permutation[i];
633 +               if (/*CONFIG_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4 && */
634 +                               s->mpeg_quant) {
635 +                       s->intra_matrix[j] = s2->mpeg_enc_ctx.intra_matrix[j2];
636 +                       s->inter_matrix[j] = s2->mpeg_enc_ctx.inter_matrix[j2];
637 +               } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
638 +                       s->intra_matrix[j] =
639 +                                       s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
640 +               } else {
641 +                       /* mpeg1/2 */
642 +                       s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
643 +                       s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
644 +               }
645 +
646 +       }
647 +       ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,
648 +                       s->intra_matrix, s->intra_quant_bias, avctx->qmin,
649 +                       31, 1);
650 +       ff_convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16,
651 +                       s->inter_matrix, s->inter_quant_bias, avctx->qmin,
652 +                       31, 0);
653 +
654 +       ff_mpeg4_transcode_init_tables(s);
655 +       for (i=1;i<32;i++) {
656 +               transcode_qmul_table[i]=(1<<QMAT_SHIFT)/(i<<1);
657 +       }
658 +
659 +       /* init the picture */
660 +
661 +
662 +       return ff_alloc_picture(s,&s->current_picture, 1);
663 +
664 +}
665 +
666 +int ff_transcode_start_picture(MpegEncContext *dec, AVCodecContext *avctx)
667 +{
668 +       Mpeg1Context *s2;
669 +       MpegEncContext *s;
670 +       int i;
671 +       struct transcode_pix_fmt *render = (struct transcode_pix_fmt*)dec->current_picture.f.data[0];
672 +       s2 = dec->avctx->priv_data;
673 +       s = s2->mpeg_enc_ctx.transcode_context;
674 +
675 +       assert(avctx);
676 +       if (dec->picture_structure != PICT_FRAME)
677 +       {
678 +               av_log(avctx, AV_LOG_ERROR, "field mode is not supported %d\n",dec->picture_structure);
679 +       }
680 +
681 +       if (!render || render->transcode_id != AV_TRANSCODE_ID ||
682 +                       !render->packet.data || !render->packet.size ) {
683 +               av_log(avctx, AV_LOG_ERROR,
684 +                               "Render token doesn't look as expected.\n");
685 +               return -1; // make sure that this is a transcode packet
686 +       }
687 +
688 +
689 +       s->input_picture_number=s->input_picture_number+1;
690 +
691 +       for(i=0; i<3; i++){
692 +               /* init last dc values */
693 +               /* note: quant matrix value (8) is implied here */
694 +               s->last_dc[i] = 128 << s->intra_dc_precision;
695 +
696 +               s->current_picture.f.error[i] = 0;
697 +       }
698 +       s->mb_skip_run = 0;
699 +       memset(s->last_mv, 0, sizeof(s->last_mv));
700 +
701 +       s->last_mv_dir = 0;
702 +
703 +
704 +
705 +       //now init the put bit contexts
706 +
707 +       s->slice_context_count=1;
708 +       init_put_bits(&s->pb, render->packet.data, render->packet.size);
709 +
710 +       //ff_mpeg4_transcode_write_picture_headers(dec,avctx); //moved to slice decoding
711 +       return 0;
712 +}
713 +
714 +
715 +
716 +
717 +void ff_transcode_end_picture(MpegEncContext *dec)
718 +{
719 +       Mpeg1Context *s2;
720 +       MpegEncContext *s;
721 +       struct transcode_pix_fmt *render;
722 +       s2 = dec->avctx->priv_data;
723 +       s = s2->mpeg_enc_ctx.transcode_context;
724 +       ff_mpeg4_stuffing(&s->pb);
725 +       avpriv_align_put_bits(&s->pb);
726 +       flush_put_bits(&s->pb);
727 +
728 +       render = (struct transcode_pix_fmt*)dec->current_picture.f.data[0];
729 +       render->packet.size=put_bits_count(&s->pb)/8;
730 +
731 +
732 +
733 +}
734 +
735 +//copy from mpegvideo_enc.c fix me
736 +
737 +static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block,
738 +               int last_index)
739 +{
740 +       int i;
741 +       const int maxlevel = s->max_qcoeff;
742 +       const int minlevel = s->min_qcoeff;
743 +       int overflow = 0;
744 +
745 +       if (s->mb_intra) {
746 +               i = 1; // skip clipping of intra dc
747 +       } else
748 +               i = 0;
749 +
750 +       for (; i <= last_index; i++) {
751 +               const int j = s->intra_scantable.scantable[i];
752 +               int level = block[j];
753 +
754 +               if (level > maxlevel) {
755 +                       level = maxlevel;
756 +                       overflow++;
757 +               } else if (level < minlevel) {
758 +                       level = minlevel;
759 +                       overflow++;
760 +               }
761 +
762 +               block[j] = level;
763 +       }
764 +
765 +       if (overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE)
766 +               av_log(s->avctx, AV_LOG_INFO,
767 +                               "warning, clipping %d dct coefficients to %d..%d\n",
768 +                               overflow, minlevel, maxlevel);
769 +}
770 +
771 +
772 +static inline int quantize_emulated_intra_c(MpegEncContext *s,
773 +               DCTELEM *block, int n,
774 +               int qscale,int dec_last_index,
775 +               int *overflow)
776 +{
777 +       int i, j, level, last_non_zero, q, start_i;
778 +       const uint8_t *scantable= s->intra_scantable.scantable;
779 +       int bias;
780 +       int qmul;
781 +       int max=0;
782 +       unsigned int threshold1, threshold2;
783 +
784 +
785 +       //qmul=(1<<QMAT_SHIFT)/(qscale<<1);
786 +       qmul=transcode_qmul_table[qscale];
787 +
788 +
789 +
790 +       q=(qscale<<1);
791 +       /* note: block[0] is assumed to be positive */
792 +       //av_log(s, AV_LOG_ERROR, "b: %d",block[0]);
793 +       if (block[0]>=0)
794 +               block[0] = (block[0] + (q >> 1)) / q;
795 +       else
796 +               block[0] =-( (-block[0] + (q >> 1)) / q);
797 +
798 +       level=block[0];
799 +       if (level>=0) {
800 +               level=((level<<1)+1)*qscale-1+(qscale&1)+1024;
801 +       } else {
802 +               level=-((((-level)<<1)+1)*qscale-1+(qscale&1))+1024;
803 +       }
804 +
805 +       max=block[0];
806 +       start_i = 1;
807 +
808 +       if (block[0]) last_non_zero = 0;
809 +       else last_non_zero=-1;
810 +       bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
811 +
812 +       threshold1= (1<<QMAT_SHIFT) - bias - 1;
813 +       threshold2= (threshold1<<1);
814 +       for(i=dec_last_index/*63*/;i>=start_i;i--) {
815 +               j = scantable[i];
816 +               level = block[j] * qmul;
817 +               if(((unsigned)(level+threshold1))>threshold2){
818 +                       last_non_zero = i;
819 +                       break;
820 +               }else{
821 +                       block[j]=0;
822 +               }
823 +       }
824 +
825 +       for(i=start_i; i<=last_non_zero; i++) {
826 +               j = scantable[i];
827 +               level = block[j] * qmul;
828 +               if(((unsigned)(level+threshold1))>threshold2){
829 +                       if(level>0){
830 +                               level= (bias + level)>>(QMAT_SHIFT);
831 +                               block[j]= level;
832 +                       }else{
833 +                               level= (bias - level)>>(QMAT_SHIFT);
834 +                               block[j]= -level;
835 +                       }
836 +                       max |=level;
837 +               }else{
838 +                       block[j]=0;
839 +               }
840 +       }
841 +       *overflow= s->max_qcoeff < max; //overflow might have happened
842 +
843 +
844 +       return last_non_zero;
845 +}
846 +
847 +
848 +
849 +static inline int quantize_c(MpegEncContext *s,
850 +               DCTELEM *block, int n,
851 +               int qscale,int dec_last_index,
852 +               int *overflow)
853 +{
854 +       int i, j, level, last_non_zero, q, start_i;
855 +       const uint8_t *scantable= s->intra_scantable.scantable;
856 +       int bias;
857 +       int qmul;
858 +       int max=0;
859 +       unsigned int threshold1, threshold2;
860 +
861 +
862 +       //qmul=(1<<QMAT_SHIFT)/(qscale<<1);
863 +       qmul=transcode_qmul_table[qscale];
864 +
865 +
866 +       if (s->mb_intra) {
867 +               if (!s->h263_aic) {
868 +                       if (n < 4)
869 +                               q = s->y_dc_scale;
870 +                       else
871 +                               q = s->c_dc_scale;
872 +                       // q = q << 3;
873 +               } else
874 +                       /* For AIC we skip quant/dequant of INTRADC */
875 +                       q = 1;// << 3;
876 +
877 +               /* note: block[0] is assumed to be positive */
878 +               block[0] = (block[0] + (q >> 1)) / q;
879 +               start_i = 1;
880 +               last_non_zero = 0;
881 +               bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
882 +       } else {
883 +               start_i = 0;
884 +               last_non_zero = -1;
885 +               bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
886 +       }
887 +       threshold1= (1<<QMAT_SHIFT) - bias - 1;
888 +       threshold2= (threshold1<<1);
889 +
890 +       for(i=dec_last_index/*63*/;i>=start_i;i--) {
891 +               j = scantable[i];
892 +               level = block[j] * qmul;
893 +               if(((unsigned)(level+threshold1))>threshold2){
894 +                       last_non_zero = i;
895 +                       break;
896 +               }else{
897 +                       block[j]=0;
898 +               }
899 +       }
900 +
901 +       for(i=start_i; i<=last_non_zero; i++) {
902 +               j = scantable[i];
903 +               level = block[j] * qmul;
904 +
905 +               //        if(   bias+level >= (1<<QMAT_SHIFT)
906 +               //           || bias-level >= (1<<QMAT_SHIFT)){
907 +               if(((unsigned)(level+threshold1))>threshold2){
908 +                       if(level>0){
909 +                               level= (bias + level)>>(QMAT_SHIFT);
910 +                               block[j]= level;
911 +                       }else{
912 +                               level= (bias - level)>>(QMAT_SHIFT);
913 +                               block[j]= -level;
914 +                       }
915 +                       max |=level;
916 +               }else{
917 +                       block[j]=0;
918 +               }
919 +       }
920 +       *overflow= s->max_qcoeff < max; //overflow might have happened
921 +
922 +
923 +
924 +       return last_non_zero;
925 +}
926 +
927 +#define ZEROS8 0,0,0,0,0,0,0,0
928 +#define ZEROS64 ZEROS8,ZEROS8,ZEROS8,ZEROS8,ZEROS8,ZEROS8,ZEROS8,ZEROS8
929 +
930 +
931 +
932 +static inline void add_zero_mb(MpegEncContext *s)
933 +{
934 +       DCTELEM zero_block[6][64]={{ZEROS64},{ZEROS64},{ZEROS64},{ZEROS64},{ZEROS64},{ZEROS64}};
935 +       const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
936 +
937 +       s->dquant=0;
938 +       ff_update_block_index(s);
939 +
940 +       if (s->pict_type==AV_PICTURE_TYPE_I) {
941 +               int q;
942 +               s->mb_intra=1;
943 +               if (s->qscale>4){ // this is not good for quantization
944 +                       s->dquant=-2;
945 +                       s->qscale=s->qscale-2;
946 +                       ff_set_qscale(s, s->qscale);
947 +               }
948 +               q=s->y_dc_scale;
949 +               zero_block[0][0]=zero_block[1][0]=
950 +                               zero_block[2][0]=zero_block[3][0]=(1024+(q>>1))/q;
951 +               q=s->c_dc_scale;
952 +               zero_block[4][0]=zero_block[5][0]=(1024+(q>>1))/q;
953 +               s->block_last_index[0]=s->block_last_index[1]=
954 +                               s->block_last_index[2]=s->block_last_index[3]=
955 +                                               s->block_last_index[4]=s->block_last_index[5]=0;
956 +
957 +               if ( (s->h263_pred || s->h263_aic))
958 +                       s->mbintra_table[mb_xy]=1;
959 +       } else {
960 +               s->mb_intra=0;
961 +               s->mv_type=MV_TYPE_16X16;
962 +               s->mv_dir=MV_DIR_FORWARD;
963 +               s->mv[0][0][0]=0;
964 +               s->mv[0][0][1]=0;
965 +               if ((s->h263_pred || s->h263_aic)) {
966 +
967 +                       if(s->mbintra_table[mb_xy])
968 +                               ff_clean_intra_table_entries(s);
969 +               } else {
970 +                       s->last_dc[0] =
971 +                                       s->last_dc[1] =
972 +                                                       s->last_dc[2] = 128 << s->intra_dc_precision;
973 +               }
974 +               s->block_last_index[0]=s->block_last_index[1]=
975 +                               s->block_last_index[2]=s->block_last_index[3]=
976 +                                               s->block_last_index[4]=s->block_last_index[5]=-1;
977 +
978 +       }
979 +
980 +
981 +
982 +       ff_mpeg4_encode_mb(s, zero_block, 0, 0);
983 +       ff_h263_update_motion_val(s);
984 +}
985 +
986 +void ff_transcode_decode_mb(MpegEncContext *dec)
987 +{
988 +       Mpeg1Context *s2;
989 +       MpegEncContext *s;
990 +       int dquant;
991 +       int i;
992 +       int dir;
993 +
994 +       int motion_x;
995 +       int motion_y;
996 +       int savetimebaseden;
997 +       int mb_xy;
998 +       int emulate=0; 
999 +       s2 = dec->avctx->priv_data;
1000 +       s = s2->mpeg_enc_ctx.transcode_context;
1001 +
1002 +       s->mb_y = dec->mb_y;
1003 +
1004 +       s->mb_x = dec->mb_x+1;
1005 +
1006 +       savetimebaseden=s->avctx->time_base.den;//the way how mpeg2 and mpeg4 handle interlaced video differs
1007 +       if (!s->progressive_sequence) {
1008 +               s->avctx->time_base.den=s->avctx->time_base.den>>1;
1009 +       }
1010 +
1011 +
1012 +
1013 +       if (dec->mb_x==0 && dec->mb_y==0) { // a bit ugly but qscale is not set before
1014 +               s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
1015 +               ff_mpeg4_transcode_write_picture_headers(dec,dec->avctx);
1016 +
1017 +       }
1018 +
1019 +
1020 +
1021 +
1022 +
1023 +       if (s->mb_x==1) {
1024 +               s->first_slice_line=s->mb_y==0;
1025 +
1026 +               s->mb_x = 0;
1027 +               ff_init_block_index(s); //necessary for prediction
1028 +
1029 +               add_zero_mb(s);
1030 +               s->mb_x = 1;
1031 +       }
1032 +       mb_xy= s->mb_y * s->mb_stride + s->mb_x;
1033 +
1034 +
1035 +
1036 +       // the decoder must be updated, important we assume mpeg12 as input
1037 +       if (!dec->mb_intra) {
1038 +               dec->last_dc[0] =
1039 +                               dec->last_dc[1] =
1040 +                                       dec->last_dc[2] = 128 << dec->intra_dc_precision;
1041 +       }
1042 +
1043 +
1044 +       dquant=-s->qscale+(dec->qscale>>1 | 1);
1045 +       if (dquant>2) dquant=2;
1046 +       else if (dquant<-2) dquant=-2;
1047 +
1048 +       if (s->pict_type == AV_PICTURE_TYPE_B) //b frames do not support dquant=1 or dquant=-1
1049 +       {
1050 +               if (dquant==1) dquant=0; // always try to quantize better not worss
1051 +               else if (dquant==-1) dquant=-2;
1052 +       }
1053 +
1054 +       s->qscale=s->qscale+dquant;
1055 +
1056 +       if (dquant) ff_set_qscale(s, s->qscale);
1057 +       s->dquant = dquant;
1058 +
1059 +
1060 +
1061 +
1062 +
1063 +       //to do convert handling
1064 +
1065 +
1066 +       s->interlaced_dct = dec->interlaced_dct;
1067 +       s->mb_intra = dec->mb_intra;
1068 +       if (!s->mb_intra) {
1069 +               s->mv_dir =  dec->mv_dir;
1070 +               s->mv_type = dec->mv_type;
1071 +               for (dir=0; dir < 2; dir++) {
1072 +                       for (i=0; i < 2; i++) {
1073 +                               s->mv[dir][i][0] = dec->mv[dir][i][0];
1074 +                               s->mv[dir][i][1] = dec->mv[dir][i][1];
1075 +                               s->field_select[dir][i] = dec->field_select[dir][i];
1076 +                       }
1077 +               }
1078 +               motion_x = motion_y = 0;
1079 +               if (s->mv_type != MV_TYPE_FIELD) {
1080 +                       if (s->mv_dir == MV_DIR_FORWARD) {
1081 +                               motion_x = s->mv[0][0][0];
1082 +                               motion_y = s->mv[0][0][1];
1083 +                       } else if (s->mv_dir == MV_DIR_BACKWARD) {
1084 +                               motion_x = s->mv[1][0][0];
1085 +                               motion_y = s->mv[1][0][1];
1086 +                       } // set motion also in direct mode TODO
1087 +               }
1088 +       }
1089 +
1090 +       if (s->pict_type == AV_PICTURE_TYPE_B){
1091 +               if (s->mb_intra) {
1092 +
1093 +                       // TODO Emulate intra blocks
1094 +                       //but first set to  non intra will break dc prediction otherwise
1095 +                       s->mb_intra=0;
1096 +                       s->mv_type=MV_TYPE_16X16;
1097 +
1098 +
1099 +                       if (s->b_code<=s->f_code) {
1100 +                               s->mv_dir = MV_DIR_FORWARD;
1101 +                               motion_y = s->mv[0][0][1]=0;
1102 +                               if (s->mb_x<(s->mb_width>>1)) {
1103 +                                       motion_x = s->mv[0][0][0]=-s->mb_x<<5;
1104 +                               } else {
1105 +                                       motion_x = s->mv[0][0][0]=(s->mb_width-s->mb_x)<<5;
1106 +                               }
1107 +                       } else {
1108 +                               motion_y = s->mv[1][0][1]=0;
1109 +                               s->mv_dir = MV_DIR_BACKWARD;
1110 +                               if (s->mb_x<(s->mb_width>>1)) {
1111 +                                       motion_x = s->mv[1][0][0]=-s->mb_x<<5;
1112 +                               } else {
1113 +                                       motion_x = s->mv[1][0][0]=(s->mb_width-s->mb_x)<<5;
1114 +                               }
1115 +                       }
1116 +                       if (abs(motion_x)>1023) {
1117 +                               s->mv_dir = MV_DIR_BACKWARD|MV_DIR_FORWARD;
1118 +                               motion_x = s->mv[1][0][0]=s->mv[0][0][0]=0;
1119 +                               av_log(s->avctx, AV_LOG_ERROR, "emulation failed intra in b picture %d %d %d\n",
1120 +                                               s->mb_x,s->mb_y,s->input_picture_number);
1121 +                               for (i=0;i<6;i++) {
1122 +                                       dec->block_last_index[i]=-1; //skip them
1123 +                               }
1124 +
1125 +                       }
1126 +
1127 +
1128 +
1129 +               //      dec->block[4][0]=2048; //should give awkward color for spotting them
1130 +
1131 +                       for (i=0;i<6;i++) {
1132 +                               dec->block[i][0]-=1024;
1133 +                       }
1134 +
1135 +
1136 +                       emulate=1;
1137 +               } else {
1138 +                       if (s->mv_type == MV_TYPE_16X8) { //this is not supported by mpeg4 emulate with 8x8
1139 +                               s->mv_type=MV_TYPE_16X16;
1140 +                               // TODO figure out if MV_TYPE_DIRECT would give a better quality
1141 +                               // figure also out if a mean motion vector will be better
1142 +                               av_log(s->avctx, AV_LOG_ERROR, "16X8 in b picture %d %d %d\n",
1143 +                                               s->mb_x,s->mb_y,s->input_picture_number);
1144 +
1145 +                       }
1146 +               }
1147 +       } else {
1148 +               if (s->mv_type == MV_TYPE_DMV) { //this is not supported by mpeg4 emulate with 16x16
1149 +                       s->mv_type=MV_TYPE_16X16;
1150 +                       // do we have to scale motion vector dunno
1151 +                       av_log(s->avctx, AV_LOG_ERROR, "DMV in p picture %d %d %d\n",
1152 +                                       s->mb_x,s->mb_y,s->input_picture_number);
1153 +               }
1154 +
1155 +       }
1156 +
1157 +       ff_update_block_index(s);
1158 +
1159 +       /* update DC predictors for P macroblocks */ //must come after the update of block ndices
1160 +       if (!s->mb_intra) {
1161 +               if ((s->h263_pred || s->h263_aic)) {
1162 +                       if(s->mbintra_table[mb_xy])
1163 +                               ff_clean_intra_table_entries(s);
1164 +               } else {
1165 +                       s->last_dc[0] =
1166 +                                       s->last_dc[1] =
1167 +                                                       s->last_dc[2] = 128 << s->intra_dc_precision;
1168 +               }
1169 +
1170 +
1171 +
1172 +       }
1173 +       else if ( (s->h263_pred || s->h263_aic))
1174 +               s->mbintra_table[mb_xy]=1;
1175 +
1176 +
1177 +
1178 +       if (!emulate) {
1179 +               for (i = 0; i < 6; i++) {
1180 +
1181 +                       if (dec->block_last_index[i]>=0) {
1182 +                               int overflow;
1183 +                               s->block_last_index[i] = quantize_c(s, dec->block[i], i, s->qscale,
1184 +                                               dec->block_last_index[i], &overflow);
1185 +                               // FIXME we could decide to change to quantizer instead of
1186 +                               // clipping
1187 +                               // JS: I don't think that would be a good idea it could lower
1188 +                               //     quality instead of improve it. Just INTRADC clipping
1189 +                               //     deserves changes in quantizer
1190 +                               if (overflow)
1191 +                                       clip_coeffs(s, dec->block[i], s->block_last_index[i]);
1192 +                       } else
1193 +                               s->block_last_index[i] = -1;
1194 +               }
1195 +       } else {
1196 +               for (i = 0; i < 6; i++) {
1197 +
1198 +                       if (dec->block_last_index[i]>=0) {
1199 +                               int overflow;
1200 +                               s->block_last_index[i] = quantize_emulated_intra_c(s, dec->block[i], i, s->qscale,
1201 +                                               dec->block_last_index[i], &overflow);
1202 +                               // FIXME we could decide to change to quantizer instead of
1203 +                               // clipping
1204 +                               // JS: I don't think that would be a good idea it could lower
1205 +                               //     quality instead of improve it. Just INTRADC clipping
1206 +                               //     deserves changes in quantizer
1207 +                               if (overflow)
1208 +                                       clip_coeffs(s, dec->block[i], s->block_last_index[i]);
1209 +                       } else
1210 +                               s->block_last_index[i] = -1;
1211 +               }
1212 +
1213 +       }
1214 +
1215 +
1216 +
1217 +
1218 +       ff_mpeg4_encode_mb(s, dec->block, motion_x, motion_y);
1219 +       ff_h263_update_motion_val(s); 
1220 +
1221 +       if (s->mb_x==s->mb_width-2) {
1222 +               s->mb_x = s->mb_width-1;
1223 +               add_zero_mb(s);
1224 +       }
1225 +
1226 +       s->avctx->time_base.den=savetimebaseden;
1227 +
1228 +
1229 +}
1230 +
1231 +void ff_mpeg4_transcode_write_picture_headers(MpegEncContext *dec,AVCodecContext* avctx)
1232 +{
1233 +       Mpeg1Context *s2;
1234 +       MpegEncContext *s;
1235 +       int save_profile;
1236 +       int save_level;
1237 +       s2 = avctx->priv_data;
1238 +       s = s2->mpeg_enc_ctx.transcode_context;
1239 +
1240 +       //now transfer the decoded data to the encoding context
1241 +
1242 +
1243 +
1244 +
1245 +
1246 +
1247 +       //picture header
1248 +       s->pict_type = dec->pict_type;
1249 +
1250 +       s->qscale = (dec->qscale>>1|1); //qscale is set in the slices maybe move this function to slice, attention so is modifing qscale in the of the picture
1251 +       ff_set_qscale(s, s->qscale);
1252 +
1253 +       s->no_rounding = 0; //does not matter related to gmc
1254 +       s->progressive_sequence = dec->progressive_sequence;
1255 +       s->current_picture_ptr->f.top_field_first = dec->top_field_first;
1256 +       s->alternate_scan = dec->alternate_scan;
1257 +       if (dec->current_picture.f.pkt_pts!=AV_NOPTS_VALUE && dec->current_picture.f.pkt_pts) {
1258 +               //thanks to god someone is supplying hopefully clean pts values, use them!!!
1259 +               s->current_picture_ptr->f.pts=dec->current_picture.f.pkt_pts;
1260 +       } else {
1261 +               // this is ugly and will probably fail,
1262 +               // it assumes a constant b frames distance
1263 +
1264 +               s->current_picture_ptr->f.pts=s->input_picture_number+0; //dirty hack, but works
1265 +
1266 +               if (s->pict_type==AV_PICTURE_TYPE_B)
1267 +               {
1268 +                       // we guess a sequence with two b frames inbetween I and P frames,
1269 +                       // as long as no DIRECT mv is used this should be fine if we are wrong
1270 +                       s->current_picture_ptr->f.pts=
1271 +                                       s->current_picture_ptr->f.pts-3;
1272 +                       //  if (s->current_picture_ptr->f.pts==s->last_time_base) s->current_picture_ptr->f.pts++;
1273 +
1274 +
1275 +               }
1276 +
1277 +       }
1278 +       if (s->pict_type!=AV_PICTURE_TYPE_B) {
1279 +               s->last_picture.f.pts=s->reordered_pts; // dirty hack
1280 +               s->reordered_pts=s->current_picture_ptr->f.pts;
1281 +       }
1282 +
1283 +
1284 +       if (s->alternate_scan) {
1285 +               ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable,ff_alternate_vertical_scan);
1286 +               ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable,ff_alternate_vertical_scan);
1287 +               ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable,ff_alternate_vertical_scan);
1288 +               ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable,ff_alternate_vertical_scan);
1289 +       } else {
1290 +               ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable,ff_zigzag_direct);
1291 +               ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable,ff_zigzag_direct);
1292 +               ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable,ff_alternate_horizontal_scan);
1293 +               ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable,ff_alternate_vertical_scan);
1294 +       }
1295 +
1296 +       s->strict_std_compliance = FF_COMPLIANCE_VERY_STRICT-1;
1297 +       s->data_partitioning = 0;
1298 +       s->f_code = dec->mpeg_f_code[0][0];
1299 +       if (dec->mpeg_f_code[0][1] > s->f_code) {
1300 +               s->f_code = dec->mpeg_f_code[0][1];
1301 +       }
1302 +
1303 +       //we select the maximum code, but not more than the maximal possible value,
1304 +
1305 +
1306 +       s->b_code = dec->mpeg_f_code[1][0];
1307 +       if (dec->mpeg_f_code[1][1] > s->b_code) {
1308 +               s->b_code = dec->mpeg_f_code[1][1];
1309 +       }
1310 +
1311 +       if (s->pict_type == AV_PICTURE_TYPE_B) {
1312 +
1313 +               if (s->b_code<=s->f_code) {
1314 +                       s->f_code=FFMIN(FFMAX(av_log2(s->width)-2,s->f_code),7);
1315 +               } else {
1316 +                       s->b_code=FFMIN(FFMAX(av_log2(s->width)-2,s->b_code),7);
1317 +               }
1318 +       }
1319 +
1320 +       //vol header
1321 +       save_profile = s->avctx->profile;
1322 +       save_level = s->avctx->level;
1323 +       s->avctx->profile = FF_PROFILE_MPEG4_ADVANCED_SIMPLE;
1324 +       s->avctx->level = 1;
1325 +
1326 +       s->width = dec->width+32; // check if we need emulation black bars
1327 +       s->height = dec->height;
1328 +       s->mb_stride = dec->mb_stride+2; //emulating black bars
1329 +       s->quarter_sample = 0;
1330 +       s->ac_pred = 0;
1331 +
1332 +       s->me.mb_var_sum_temp    =
1333 +                       s->me.mc_mb_var_sum_temp = 0;
1334 +
1335 +
1336 +
1337 +       ff_set_frame_distances(s);
1338 +       ff_set_mpeg4_time(s);
1339 +
1340 +       s->me.scene_change_score=0;
1341 +
1342 +       if (s2->closed_gop) s->flags|=CODEC_FLAG_CLOSED_GOP;
1343 +       else s->flags&=~CODEC_FLAG_CLOSED_GOP;//transverse gop flag
1344 +
1345 +
1346 +       ff_mpeg4_encode_picture_header(s, 0);
1347 +       s->avctx->profile = save_profile;
1348 +       s->avctx->level = save_level;
1349 +
1350 +
1351 +
1352 +
1353 +}
1354 diff --git a/libavcodec/transcode.h b/libavcodec/transcode.h
1355 new file mode 100644
1356 index 0000000..c1c8c85
1357 --- /dev/null
1358 +++ b/libavcodec/transcode.h
1359 @@ -0,0 +1,69 @@
1360 +/*
1361 + * Copyright (C) 2012 Marten Richter
1362 + *
1363 + * This file is part of Libav.
1364 + *
1365 + * Libav is free software; you can redistribute it and/or
1366 + * modify it under the terms of the GNU Lesser General Public
1367 + * License as published by the Free Software Foundation; either
1368 + * version 2.1 of the License, or (at your option) any later version.
1369 + *
1370 + * Libav is distributed in the hope that it will be useful,
1371 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1372 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1373 + * Lesser General Public License for more details.
1374 + *
1375 + * You should have received a copy of the GNU Lesser General Public
1376 + * License along with Libav; if not, write to the Free Software
1377 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1378 + */
1379 +
1380 +#ifndef AVCODEC_TRANSCODE_H
1381 +#define AVCODEC_TRANSCODE_H
1382 +
1383 +/**
1384 + * @file
1385 + * @ingroup lavc_codec_hwaccel_mpeg4_transcode
1386 + * Public libavcodec Mpeg4TranscodeHeader header.
1387 + */
1388 +
1389 +#include "avcodec.h"
1390 +
1391 +/**
1392 + * @defgroup lavc_codec_hwaccel_mpeg4_transcode Mpeg4Transcode
1393 + * @ingroup lavc_codec_hwaccel
1394 + *
1395 + * @{
1396 + */
1397 +
1398 +#define AV_TRANSCODE_ID                    0x54524E53  /**< special value to ensure that regular pixel routines haven't corrupted the struct
1399 +                                                                         the number  speak for the letters TRNS */
1400 +
1401 +struct transcode_pix_fmt {
1402 +    /** The field contains the special constant value AV_TRANSCODE_ID.
1403 +        It is used as a test that the application correctly uses the API,
1404 +        and that there is no corruption caused by pixel routines.
1405 +        - application - set during initialization
1406 +        - libavcodec  - unchanged
1407 +    */
1408 +    int             transcode_id;
1409 +
1410 +    /** AVPacket structure containing the buffer getting all the transcoded data
1411 +        - application - set the pointer during initialization
1412 +        - libavcodec  - fills bitstream to packet
1413 +    */
1414 +    AVPacket          packet;
1415 +
1416 +    /** Indicates that a new frame start in this frame
1417 +        - application - unchanged
1418 +        - libavcodec  - set
1419 +    */
1420 +    int new_frame;
1421 +
1422 +};
1423 +
1424 +/**
1425 + * @}
1426 + */
1427 +
1428 +#endif /* AVCODEC_XVMC_H */
1429 diff --git a/libavcodec/transcode_internal.h b/libavcodec/transcode_internal.h
1430 new file mode 100644
1431 index 0000000..b837fde
1432 --- /dev/null
1433 +++ b/libavcodec/transcode_internal.h
1434 @@ -0,0 +1,34 @@
1435 +/*
1436 + * Transcode internal functions
1437 + *
1438 + * This file is part of Libav.
1439 + *
1440 + * Libav is free software; you can redistribute it and/or
1441 + * modify it under the terms of the GNU Lesser General Public
1442 + * License as published by the Free Software Foundation; either
1443 + * version 2.1 of the License, or (at your option) any later version.
1444 + *
1445 + * Libav is distributed in the hope that it will be useful,
1446 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1447 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1448 + * Lesser General Public License for more details.
1449 + *
1450 + * You should have received a copy of the GNU Lesser General Public
1451 + * License along with Libav; if not, write to the Free Software
1452 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1453 + */
1454 +
1455 +#ifndef AVCODEC_TRANSCODE_INTERNAL_H
1456 +#define AVCODEC_TRANSCODE_INTERNAL_H
1457 +
1458 +#include "avcodec.h"
1459 +#include "mpegvideo.h"
1460 +
1461 +int ff_mpeg_transcode_decode_postinit(AVCodecContext* avctx);
1462 +void ff_mpeg4_transcode_write_picture_headers(MpegEncContext *dec,AVCodecContext* avctx);
1463 +void ff_transcode_decode_mb(MpegEncContext *dec);
1464 +int ff_transcode_start_picture(MpegEncContext *dec, AVCodecContext *avctx);
1465 +void ff_transcode_end_picture(MpegEncContext *dec);
1466 +void ff_mpeg4_transcode_mb(MpegEncContext * s, DCTELEM block[6][64], int motion_x, int motion_y);
1467 +
1468 +#endif /* AVCODEC_TRANSCODE_INTERNAL_H */
1469 diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
1470 index bd898bd..9600629 100644
1471 --- a/libavutil/pixfmt.h
1472 +++ b/libavutil/pixfmt.h
1473 @@ -157,6 +157,8 @@ enum PixelFormat {
1474      PIX_FMT_GBRP10LE,  ///< planar GBR 4:4:4 30bpp, little endian
1475      PIX_FMT_GBRP16BE,  ///< planar GBR 4:4:4 48bpp, big endian
1476      PIX_FMT_GBRP16LE,  ///< planar GBR 4:4:4 48bpp, little endian
1477 +
1478 +    PIX_FMT_TRANSCODE, ///< HW decoding of mpeg4 data[0] contains a transcode_pix_fmt structure
1479      PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
1480  };
1481  
1482 -- 
1483 1.7.10.4
1484