]> git.sesse.net Git - vlc/blobdiff - modules/stream_out/transcode.c
* rtp, display: update p_sout->i_out_pace_nocontrol.
[vlc] / modules / stream_out / transcode.c
index 3065a04d49ebd3da9faa21059e54ffd61bc5908b..9238e0bdeb45cc6e67a1cae4cb6ca89e0644f9f7 100644 (file)
@@ -2,7 +2,7 @@
  * transcode.c: transcoding stream output module
  *****************************************************************************
  * Copyright (C) 2003-2004 VideoLAN
- * $Id: transcode.c,v 1.78 2004/02/20 19:21:25 massiot Exp $
+ * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
 #   include <avcodec.h>
 #endif
 
+#if LIBAVCODEC_BUILD < 4704
+#   define AV_NOPTS_VALUE 0
+#endif
+
 /*****************************************************************************
  * Exported prototypes
  *****************************************************************************/
@@ -782,7 +786,7 @@ static int transcode_audio_ffmpeg_new( sout_stream_t *p_stream,
     id->p_encoder->fmt_out.i_bitrate = id->f_dst.i_bitrate;
 
     id->p_encoder->p_module =
-        module_Need( id->p_encoder, "encoder", NULL );
+        module_Need( id->p_encoder, "encoder", NULL, 0 );
     if( !id->p_encoder->p_module )
     {
         vlc_object_destroy( id->p_encoder );
@@ -1041,6 +1045,16 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
         id->ff_dec_c->width     = id->f_src.video.i_width;
         id->ff_dec_c->height    = id->f_src.video.i_height;
         id->ff_dec_c->pix_fmt   = get_ff_chroma( id->f_src.i_codec );
+
+#if LIBAVCODEC_BUILD >= 4687
+        if( id->ff_dec_c->width )
+        id->ff_dec_c->sample_aspect_ratio =
+            av_d2q( id->f_src.video.i_aspect / (double)VOUT_ASPECT_FACTOR *
+                    id->ff_dec_c->height / id->ff_dec_c->width, 255 );
+#else
+        id->ff_dec_c->aspect_ratio =
+            id->f_src.video.i_aspect / (float)VOUT_ASPECT_FACTOR;
+#endif
     }
     else
     {
@@ -1062,9 +1076,54 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
         id->ff_dec_c = avcodec_alloc_context();
         id->ff_dec_c->width         = id->f_src.video.i_width;
         id->ff_dec_c->height        = id->f_src.video.i_height;
+        id->ff_dec_c->bits_per_sample=id->f_src.video.i_bits_per_pixel;
         /* id->ff_dec_c->bit_rate      = id->f_src.i_bitrate; */
-        id->ff_dec_c->extradata_size= id->f_src.i_extra;
-        id->ff_dec_c->extradata     = id->f_src.p_extra;
+
+        if( id->f_src.i_extra > 0 )
+        {
+            if( i_ff_codec == CODEC_ID_SVQ3 )
+            {
+                int i_size = id->f_src.i_extra;
+                uint8_t *p;
+
+                id->ff_dec_c->extradata_size = i_size + 12;
+                p = id->ff_dec_c->extradata  = malloc( i_size + 12 );
+
+                memcpy( &p[0],  "SVQ3", 4 );
+                memset( &p[4], 0, 8 );
+                memcpy( &p[12], id->f_src.p_extra, i_size );
+
+                /* Now remove all atoms before the SMI one */
+                if( id->ff_dec_c->extradata_size > 0x5a && strncmp( &p[0x56], "SMI ", 4 ) )
+                {
+                    uint8_t *psz = &p[0x52];
+
+                    while( psz < &p[id->ff_dec_c->extradata_size - 8] )
+                    {
+                        int i_size = GetDWBE( psz );
+                        if( i_size <= 1 )
+                        {
+                            /* FIXME handle 1 as long size */
+                            break;
+                        }
+                        if( !strncmp( &psz[4], "SMI ", 4 ) )
+                        {
+                            memmove( &p[0x52], psz, &p[id->ff_dec_c->extradata_size] - psz );
+                            break;
+                        }
+                        psz += i_size;
+                    }
+                }
+            }
+            else
+            {
+                id->ff_dec_c->extradata_size= id->f_src.i_extra;
+                id->ff_dec_c->extradata = malloc( id->f_src.i_extra + FF_INPUT_BUFFER_PADDING_SIZE );
+
+                memcpy( id->ff_dec_c->extradata, id->f_src.p_extra, id->f_src.i_extra );
+                memset( (uint8_t*)id->ff_dec_c->extradata + id->f_src.i_extra, 0, FF_INPUT_BUFFER_PADDING_SIZE );
+            }
+        }
         id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
         id->ff_dec_c->error_resilience= -1;
         id->ff_dec_c->get_buffer    = transcode_video_ffmpeg_getframebuf;
@@ -1075,7 +1134,7 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
             msg_Err( p_stream, "cannot open decoder" );
             return VLC_EGENERIC;
         }
-
+#if 0
         if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
         {
             int b_gotpicture;
@@ -1093,6 +1152,7 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
                                   id->ff_dec_c->extradata_size );
             free( p_vol );
         }
+#endif
     }
 
     /* Open encoder */
@@ -1164,7 +1224,7 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
     id->p_vresample      = NULL;
 
     id->p_encoder->p_module =
-        module_Need( id->p_encoder, "encoder", NULL );
+        module_Need( id->p_encoder, "encoder", NULL, 0 );
 
     if( !id->p_encoder->p_module )
     {
@@ -1277,8 +1337,6 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
         picture_t * p_pic;
         int i_plane;
 
-        p_pic = malloc(sizeof(picture_t));
-
         /* decode frame */
         frame = id->p_ff_pic;
         p_sys->i_input_pts = in->i_pts;
@@ -1298,7 +1356,8 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
             b_gotpicture = 1;
 
             /* Set PTS */
-            frame->pts = p_sys->i_input_pts;
+            frame->pts = p_sys->i_input_pts ? p_sys->i_input_pts :
+                         AV_NOPTS_VALUE;
         }
 
         if( i_used < 0 )
@@ -1316,7 +1375,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
 
         /* Get the pts of the decoded frame if any, otherwise keep the
          * interpolated one */
-        if( frame->pts > 0 )
+        if( frame->pts != AV_NOPTS_VALUE )
         {
             p_sys->i_output_pts = frame->pts;
         }
@@ -1362,7 +1421,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
             id->p_encoder->fmt_out.p_extra = NULL;
 
             id->p_encoder->p_module =
-                module_Need( id->p_encoder, "encoder", NULL );
+                module_Need( id->p_encoder, "encoder", NULL, 0 );
             if( !id->p_encoder->p_module )
             {
                 vlc_object_destroy( id->p_encoder );
@@ -1440,7 +1499,9 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
                                    id->ff_dec_c->pix_fmt,
                                    id->ff_dec_c->width, id->ff_dec_c->height );
 
+#if LIBAVCODEC_BUILD >= 4685
             id->p_ff_pic_tmp0->interlaced_frame = 0;
+#endif
             id->p_ff_pic_tmp0->repeat_pict = frame->repeat_pict;
             frame = id->p_ff_pic_tmp0;
         }
@@ -1468,9 +1529,9 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
                          (AVPicture*)frame, id->ff_dec_c->pix_fmt,
                          id->ff_dec_c->width, id->ff_dec_c->height );
 
-            id->p_ff_pic_tmp1->interlaced_frame = frame->interlaced_frame;
             id->p_ff_pic_tmp1->repeat_pict = frame->repeat_pict;
-#if LIBAVCODEC_BUILD >= 4684
+#if LIBAVCODEC_BUILD >= 4685
+            id->p_ff_pic_tmp1->interlaced_frame = frame->interlaced_frame;
             id->p_ff_pic_tmp1->top_field_first = frame->top_field_first;
 #endif
             frame = id->p_ff_pic_tmp1;
@@ -1510,15 +1571,16 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
             img_resample( id->p_vresample, (AVPicture*)id->p_ff_pic_tmp2,
                           (AVPicture*)frame );
 
-            id->p_ff_pic_tmp2->interlaced_frame = frame->interlaced_frame;
             id->p_ff_pic_tmp2->repeat_pict = frame->repeat_pict;
-#if LIBAVCODEC_BUILD >= 4684
+#if LIBAVCODEC_BUILD >= 4685
+            id->p_ff_pic_tmp2->interlaced_frame = frame->interlaced_frame;
             id->p_ff_pic_tmp2->top_field_first = frame->top_field_first;
 #endif
             frame = id->p_ff_pic_tmp2;
         }
 
         /* Encoding */
+        p_pic = malloc(sizeof(picture_t));
         vout_InitPicture( VLC_OBJECT(p_stream), p_pic,
                           id->p_encoder->fmt_in.i_codec,
                           id->f_dst.video.i_width, id->f_dst.video.i_height,
@@ -1530,8 +1592,11 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
             p_pic->p[i_plane].i_pitch = frame->linesize[i_plane];
             if ( p_sys->i_threads >= 1 )
             {
-                p_pic->p[i_plane].p_pixels = malloc(p_pic->p[i_plane].i_lines * p_pic->p[i_plane].i_pitch);
-                p_stream->p_vlc->pf_memcpy(p_pic->p[i_plane].p_pixels, frame->data[i_plane], p_pic->p[i_plane].i_lines * p_pic->p[i_plane].i_pitch);
+                p_pic->p[i_plane].p_pixels = malloc(p_pic->p[i_plane].i_lines *
+                                                    p_pic->p[i_plane].i_pitch);
+                p_stream->p_vlc->pf_memcpy( p_pic->p[i_plane].p_pixels,
+                    frame->data[i_plane], p_pic->p[i_plane].i_lines *
+                     p_pic->p[i_plane].i_pitch );
             }
             else
             {
@@ -1542,9 +1607,9 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
         /* Set the pts of the frame being encoded */
         p_pic->date = p_sys->i_output_pts;
 
-        p_pic->b_progressive = !frame->interlaced_frame;
         p_pic->i_nb_fields = frame->repeat_pict;
-#if LIBAVCODEC_BUILD >= 4684
+#if LIBAVCODEC_BUILD >= 4685
+        p_pic->b_progressive = !frame->interlaced_frame;
         p_pic->b_top_field_first = frame->top_field_first;
 #endif
 
@@ -1580,6 +1645,9 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
                 p_out->i_dts = p_block->i_dts;
                 p_out->i_pts = p_block->i_pts;
                 p_out->i_length = p_block->i_length;
+                p_out->i_flags =
+                        (p_block->i_flags << SOUT_BUFFER_FLAGS_BLOCK_SHIFT)
+                          & SOUT_BUFFER_FLAGS_BLOCK_MASK;
                 sout_BufferChain( out, p_out );
 
                 p_block = p_block->p_next;
@@ -1638,6 +1706,9 @@ static int EncoderThread( sout_stream_sys_t * p_sys )
             p_out->i_dts = p_block->i_dts;
             p_out->i_pts = p_block->i_pts;
             p_out->i_length = p_block->i_length;
+            p_out->i_flags =
+                (p_block->i_flags << SOUT_BUFFER_FLAGS_BLOCK_SHIFT)
+                  & SOUT_BUFFER_FLAGS_BLOCK_MASK;
             sout_BufferChain( &p_sys->p_buffers, p_out );
 
             p_block = p_block->p_next;
@@ -1687,7 +1758,7 @@ static int transcode_video_ffmpeg_getframebuf(struct AVCodecContext *p_context,
     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_context->opaque;
 
     /* Set PTS */
-    p_frame->pts = p_sys->i_input_pts;
+    p_frame->pts = p_sys->i_input_pts ? p_sys->i_input_pts : AV_NOPTS_VALUE;
 
     return avcodec_default_get_buffer( p_context, p_frame );
 }