Example #1
0
    def _createStream(self):
        """Create the AVStream and open the codec.
        """
        
        # Allocate a new stream
        stream = avformat.av_new_stream(self._formatCtx, self._formatCtx.nb_streams)
        # Initialize it as a video stream
        avcodec.avcodec_get_context_defaults2(stream.codec.contents, decls.CODEC_TYPE_VIDEO)

        outputFormat = self._formatCtx.oformat.contents
        codecCtx = stream.codec.contents
        
        if outputFormat.flags & decls.AVFMT_GLOBALHEADER:
            stream.codec.contents.flags |= decls.CODEC_FLAG_GLOBAL_HEADER
        
        # Prepare the codec...
        codecId = avformat.av_guess_codec(outputFormat, decls.CODEC_TYPE_VIDEO, fileName=self._formatCtx.filename)
        if codecId is None:
            raise ValueError("Could not determine video codec to use for encoding the video.")
        codec = avcodec.avcodec_find_encoder(codecId)
        if codec is None:
            raise ValueError("Could not find encoder.")

        if codec.supported_framerates:
            print "mediafile: supported framerates available"
        else:
            print "mediafile: supported framerates not available"

        codecCtx.codec_id = codecId
        num,den = self._frameRate
        codecCtx.time_base.den = num
        codecCtx.time_base.num = den
        width,height = self._size
        codecCtx.width = width
        codecCtx.height = height
        codecCtx.sample_aspect_ratio = avutil.av_d2q(self._pixelAspect, 255)
        codecCtx.pix_fmt = decls.PIX_FMT_YUV420P
        stream.sample_aspect_ratio = codecCtx.sample_aspect_ratio
        
        # Check if the codec supports the pixel format (if not, switch the format)
        if codec.pix_fmts:
            i = 0
            while codec.pix_fmts[i]!=-1:
                if codecCtx.pix_fmt==codec.pix_fmts[i]:
                    break
                i += 1
            else:
                codecCtx.pix_fmt = codec.pix_fmts[0]
        
        # Open the codec
        avcodec.avcodec_open(codecCtx, codec)
        
        return stream
Example #2
0
    def __init__(self, formatCtx, size, frameRate, pixelAspect):
        """Constructor.
        
        formatCtx is a AVFormatContext object.
        size is a tuple (width, height) containing the resolution of the
        video images.
        frameRate is the target framerate. It can be a single int or float
        or a tuple (num,den).
        pixelAspect is a float containing the pixel aspect ratio.
        """
        self._formatCtx = formatCtx
        self._size = size
        self._pixelAspect = pixelAspect
        
        try:
            # Check if frameRate is a 2-tuple
            num,den = frameRate
        except:
            # Turn the framerate into a rational...
            r = avutil.av_d2q(frameRate, 255)
            frameRate = (r.num, r.den)
        
        # The framerate as a tuple (num, den).
        self._frameRate = frameRate

        # Create an AVStream
        self._stream = self._createStream()
        
        # Get the codec context of the stream
        self._codecCtx = self._stream.codec.contents
        
        width,height = self._size
        # Set up the buffer that can store the encoded frame
        self._bufSize = 6*width*height+200
        self._buffer = ctypes.create_string_buffer(self._bufSize)

        self._frame = avcodec.avcodec_alloc_frame()
        if self._frame is None:
            raise MemoryError("Failed to allocate AVFrame object")
        avcodec.avpicture_alloc(self._frame, self._codecCtx.pix_fmt, width, height)

        # Allocate a picture for the converted image...
        self._picture = decls.AVPicture()
        avcodec.avpicture_alloc(self._picture, self._codecCtx.pix_fmt, width, height)
        # Get the size of the destination image buffer
        self._pictureSize = avcodec.avpicture_get_size(self._codecCtx.pix_fmt, width, height)
        
        self._pkt = decls.AVPacket()
        avformat.av_init_packet(self._pkt)
        #pkt.stream_index = outputstream.index
        
        self._currentPts = 0