Ejemplo n.º 1
0
static int end_frame(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    BufferSinkContext *buf = inlink->dst->priv;

    av_assert1(inlink->cur_buf);
    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
        /* realloc fifo size */
        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot buffer more frames. Consume some available frames "
                   "before adding new ones.\n");
            return AVERROR(ENOMEM);
        }
    }

    /* cache frame */
    av_fifo_generic_write(buf->fifo,
                          &inlink->cur_buf, sizeof(AVFilterBufferRef *), NULL);
    inlink->cur_buf = NULL;
    if (buf->warning_limit &&
        av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) {
        av_log(ctx, AV_LOG_WARNING,
               "%d buffers queued in %s, something may be wrong.\n",
               buf->warning_limit,
               (char *)av_x_if_null(ctx->name, ctx->filter->name));
        buf->warning_limit *= 10;
    }
    return 0;
}
Ejemplo n.º 2
0
bool ExportFFmpeg::EncodeAudioFrame(int16_t *pFrame, int frameSize)
{
   AVPacket pkt;
   int nBytesToWrite = 0;
   uint8_t *pRawSamples = NULL;
   int nAudioFrameSizeOut = default_frame_size * mEncAudioCodecCtx->channels * sizeof(int16_t);
   int ret;

   nBytesToWrite = frameSize;
   pRawSamples  = (uint8_t*)pFrame;
   av_fifo_realloc2(mEncAudioFifo, av_fifo_size(mEncAudioFifo) + frameSize);

   // Put the raw audio samples into the FIFO.
   ret = av_fifo_generic_write(mEncAudioFifo, pRawSamples, nBytesToWrite,NULL);

   wxASSERT(ret == nBytesToWrite);

   if (nAudioFrameSizeOut > mEncAudioFifoOutBufSiz) {
      wxLogError(wxT("FFmpeg : ERROR - nAudioFrameSizeOut too large."));
      return false;
   }

   // Read raw audio samples out of the FIFO in nAudioFrameSizeOut byte-sized groups to encode.
   while ((ret = av_fifo_size(mEncAudioFifo)) >= nAudioFrameSizeOut)
   {
      ret = av_fifo_generic_read(mEncAudioFifo, mEncAudioFifoOutBuf, nAudioFrameSizeOut, NULL);

      av_init_packet(&pkt);

      int ret= encode_audio(mEncAudioCodecCtx,
         &pkt,                          // out
         (int16_t*)mEncAudioFifoOutBuf, // in
         default_frame_size);
      if (ret < 0)
      {
         wxLogError(wxT("FFmpeg : ERROR - Can't encode audio frame."));
         return false;
      }
      if (ret == 0)
         continue;

      // Rescale from the codec time_base to the AVStream time_base.
      if (pkt.pts != int64_t(AV_NOPTS_VALUE))
         pkt.pts = av_rescale_q(pkt.pts, mEncAudioCodecCtx->time_base, mEncAudioStream->time_base);
      if (pkt.dts != int64_t(AV_NOPTS_VALUE))
         pkt.dts = av_rescale_q(pkt.dts, mEncAudioCodecCtx->time_base, mEncAudioStream->time_base);
      //wxLogDebug(wxT("FFmpeg : (%d) Writing audio frame with PTS: %lld."), mEncAudioCodecCtx->frame_number, (long long) pkt.pts);

      pkt.stream_index = mEncAudioStream->index;

      // Write the encoded audio frame to the output file.
      if ((ret = av_interleaved_write_frame(mEncFormatCtx, &pkt)) < 0)
      {
         wxLogError(wxT("FFmpeg : ERROR - Failed to write audio frame to file."));
         return false;
      }
      av_free_packet(&pkt);
   }
   return true;
}
status_t
AVCodecEncoder::_EncodeAudio(const void* _buffer, int64 frameCount,
	media_encode_info* info)
{
	TRACE("AVCodecEncoder::_EncodeAudio(%p, %lld, %p)\n", _buffer, frameCount,
		info);

	if (fChunkBuffer == NULL)
		return B_NO_MEMORY;

	status_t ret = B_OK;

	const uint8* buffer = reinterpret_cast<const uint8*>(_buffer);

	size_t inputSampleSize = fInputFormat.u.raw_audio.format
		& media_raw_audio_format::B_AUDIO_SIZE_MASK;
	size_t inputFrameSize = inputSampleSize
		* fInputFormat.u.raw_audio.channel_count;

	size_t bufferSize = frameCount * inputFrameSize;
	bufferSize = min_c(bufferSize, kDefaultChunkBufferSize);

	if (fContext->frame_size > 1) {
		// Encoded audio. Things work differently from raw audio. We need
		// the fAudioFifo to pipe data.
		if (av_fifo_realloc2(fAudioFifo,
				av_fifo_size(fAudioFifo) + bufferSize) < 0) {
			TRACE("  av_fifo_realloc2() failed\n");
            return B_NO_MEMORY;
        }
        av_fifo_generic_write(fAudioFifo, const_cast<uint8*>(buffer),
        	bufferSize, NULL);

		int frameBytes = fContext->frame_size * inputFrameSize;
		uint8* tempBuffer = new(std::nothrow) uint8[frameBytes];
		if (tempBuffer == NULL)
			return B_NO_MEMORY;

		// Encode as many chunks as can be read from the FIFO.
		while (av_fifo_size(fAudioFifo) >= frameBytes) {
			av_fifo_generic_read(fAudioFifo, tempBuffer, frameBytes, NULL);

			ret = _EncodeAudio(tempBuffer, frameBytes, fContext->frame_size,
				info);
			if (ret != B_OK)
				break;
		}

		delete[] tempBuffer;
	} else {
		// Raw audio. The number of bytes returned from avcodec_encode_audio()
		// is always the same as the number of input bytes.
		return _EncodeAudio(buffer, bufferSize, frameCount,
			info);
	}

	return ret;
}
Ejemplo n.º 4
0
int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx,
                                               AVFrame *frame)
{
    BufferSourceContext *s = ctx->priv;
    AVFrame *copy;
    int refcounted, ret;

    if (!frame) {
        s->eof = 1;
        return 0;
    } else if (s->eof)
        return AVERROR(EINVAL);

    refcounted = !!frame->buf[0];

    switch (ctx->outputs[0]->type) {
    case AVMEDIA_TYPE_VIDEO:
        CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
                                 frame->format);
        break;
    case AVMEDIA_TYPE_AUDIO:
        CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
                                 frame->format);
        break;
    default:
        return AVERROR(EINVAL);
    }

    if (!av_fifo_space(s->fifo) &&
        (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
                                         sizeof(copy))) < 0)
        return ret;

    if (!(copy = av_frame_alloc()))
        return AVERROR(ENOMEM);

    if (refcounted) {
        av_frame_move_ref(copy, frame);
    } else {
        ret = av_frame_ref(copy, frame);
        if (ret < 0) {
            av_frame_free(&copy);
            return ret;
        }
    }

    if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
        if (refcounted)
            av_frame_move_ref(frame, copy);
        av_frame_free(&copy);
        return ret;
    }

    return 0;
}
Ejemplo n.º 5
0
static void write_buf(AVFilterContext *ctx, AVFilterBufferRef *buf)
{
    BufferSinkContext *sink = ctx->priv;

    if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
        (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
            av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
            return;
    }

    av_fifo_generic_write(sink->fifo, &buf, sizeof(buf), NULL);
}
Ejemplo n.º 6
0
Archivo: fifo.c Proyecto: 1c0n/xbmc
int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
{
    unsigned int old_size = f->end - f->buffer;
    if(size + (unsigned)av_fifo_size(f) < size)
        return AVERROR(EINVAL);

    size += av_fifo_size(f);

    if (old_size < size)
        return av_fifo_realloc2(f, FFMAX(size, 2*size));
    return 0;
}
Ejemplo n.º 7
0
Archivo: vf_fps.c Proyecto: AVbin/libav
static int write_to_fifo(AVFifoBuffer *fifo, AVFrame *buf)
{
    int ret;

    if (!av_fifo_space(fifo) &&
        (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
        av_frame_free(&buf);
        return ret;
    }

    av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL);
    return 0;
}
Ejemplo n.º 8
0
static void end_frame(AVFilterLink *link)
{
    AVFilterContext   *ctx = link->dst;
    BufferSinkContext *sink = ctx->priv;

    if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
        (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
            av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
            return;
    }

    av_fifo_generic_write(sink->fifo, &link->cur_buf, sizeof(link->cur_buf), NULL);
    link->cur_buf = NULL;
}
Ejemplo n.º 9
0
int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples)
{
    int i, ret, buf_size;

    if ((ret = av_samples_get_buffer_size(&buf_size, af->channels, nb_samples,
                                          af->sample_fmt, 1)) < 0)
        return ret;

    for (i = 0; i < af->nb_buffers; i++) {
        if ((ret = av_fifo_realloc2(af->buf[i], buf_size)) < 0)
            return ret;
    }
    af->allocated_samples = nb_samples;
    return 0;
}
Ejemplo n.º 10
0
int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
{
    BufferSourceContext *c = s->priv;
    int ret;

    if (!av_fifo_space(c->fifo) &&
        (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
                                         sizeof(buf))) < 0)
        return ret;

//     CHECK_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);

    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
        return ret;

    return 0;
}
Ejemplo n.º 11
0
static int add_buffer_ref(AVFilterContext *ctx, AVFrame *ref)
{
    BufferSinkContext *buf = ctx->priv;

    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
        /* realloc fifo size */
        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot buffer more frames. Consume some available frames "
                   "before adding new ones.\n");
            return AVERROR(ENOMEM);
        }
    }

    /* cache frame */
    av_fifo_generic_write(buf->fifo, &ref, sizeof(AVFilterBufferRef *), NULL);
    return 0;
}
Ejemplo n.º 12
0
static void end_frame(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    BufferSinkContext *buf = inlink->dst->priv;

    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
        /* realloc fifo size */
        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "Cannot buffer more frames. Consume some available frames "
                   "before adding new ones.\n");
            return;
        }
    }

    /* cache frame */
    av_fifo_generic_write(buf->fifo,
                          &inlink->cur_buf, sizeof(AVFilterBufferRef *), NULL);
}
Ejemplo n.º 13
0
int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush,
                        int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int),
                        int (*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *))
{
    int i, ret;

    if (pkt) {
        AVStream *st = s->streams[pkt->stream_index];
        AudioInterleaveContext *aic = st->priv_data;
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            unsigned new_size = av_fifo_size(aic->fifo) + pkt->size;
            if (new_size > aic->fifo_size) {
                if (av_fifo_realloc2(aic->fifo, new_size) < 0)
                    return AVERROR(ENOMEM);
                aic->fifo_size = new_size;
            }
            av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL);
        } else {
            // rewrite pts and dts to be decoded time line position
            pkt->pts = pkt->dts = aic->dts;
            aic->dts += pkt->duration;
            if ((ret = ff_interleave_add_packet(s, pkt, compare_ts)) < 0)
                return ret;
        }
        pkt = NULL;
    }

    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            AVPacket new_pkt = { 0 };
            while ((ret = interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
                if ((ret = ff_interleave_add_packet(s, &new_pkt, compare_ts)) < 0)
                    return ret;
            }
            if (ret < 0)
                return ret;
        }
    }

    return get_packet(s, out, NULL, flush);
}
Ejemplo n.º 14
0
static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
{
    FLACParseContext *fpc = s->priv_data;
    FLACHeaderMarker *curr;
    int nb_headers;
    const uint8_t *read_end   = buf;
    const uint8_t *read_start = buf;

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        FLACFrameInfo fi;
        if (frame_header_is_valid(avctx, buf, &fi))
            s->duration = fi.blocksize;
        *poutbuf      = buf;
        *poutbuf_size = buf_size;
        return buf_size;
    }

    fpc->avctx = avctx;
    if (fpc->best_header_valid)
        return get_best_header(fpc, poutbuf, poutbuf_size);

    /* If a best_header was found last call remove it with the buffer data. */
    if (fpc->best_header && fpc->best_header->best_child) {
        FLACHeaderMarker *temp;
        FLACHeaderMarker *best_child = fpc->best_header->best_child;

        /* Remove headers in list until the end of the best_header. */
        for (curr = fpc->headers; curr != best_child; curr = temp) {
            if (curr != fpc->best_header) {
                av_log(avctx, AV_LOG_DEBUG,
                       "dropping low score %i frame header from offset %i to %i\n",
                       curr->max_score, curr->offset, curr->next->offset);
            }
            temp = curr->next;
            av_freep(&curr->link_penalty);
            av_free(curr);
            fpc->nb_headers_buffered--;
        }
        /* Release returned data from ring buffer. */
        av_fifo_drain(fpc->fifo_buf, best_child->offset);

        /* Fix the offset for the headers remaining to match the new buffer. */
        for (curr = best_child->next; curr; curr = curr->next)
            curr->offset -= best_child->offset;

        fpc->nb_headers_buffered--;
        best_child->offset = 0;
        fpc->headers       = best_child;
        if (fpc->nb_headers_buffered >= FLAC_MIN_HEADERS) {
            fpc->best_header = best_child;
            return get_best_header(fpc, poutbuf, poutbuf_size);
        }
        fpc->best_header   = NULL;
    } else if (fpc->best_header) {
        /* No end frame no need to delete the buffer; probably eof */
        FLACHeaderMarker *temp;

        for (curr = fpc->headers; curr != fpc->best_header; curr = temp) {
            temp = curr->next;
            av_freep(&curr->link_penalty);
            av_free(curr);
        }
        fpc->headers = fpc->best_header->next;
        av_freep(&fpc->best_header->link_penalty);
        av_freep(&fpc->best_header);
    }

    /* Find and score new headers. */
    while ((buf && read_end < buf + buf_size &&
            fpc->nb_headers_buffered < FLAC_MIN_HEADERS)
           || (!buf && !fpc->end_padded)) {
        int start_offset;

        /* Pad the end once if EOF, to check the final region for headers. */
        if (!buf) {
            fpc->end_padded      = 1;
            buf_size = MAX_FRAME_HEADER_SIZE;
            read_end = read_start + MAX_FRAME_HEADER_SIZE;
        } else {
            /* The maximum read size is the upper-bound of what the parser
               needs to have the required number of frames buffered */
            int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1;
            read_end       = read_end + FFMIN(buf + buf_size - read_end,
                                              nb_desired * FLAC_AVG_FRAME_SIZE);
        }

        if (!av_fifo_space(fpc->fifo_buf) &&
            av_fifo_size(fpc->fifo_buf) / FLAC_AVG_FRAME_SIZE >
            fpc->nb_headers_buffered * 10) {
            /* There is less than one valid flac header buffered for 10 headers
             * buffered. Therefore the fifo is most likely filled with invalid
             * data and the input is not a flac file. */
            goto handle_error;
        }

        /* Fill the buffer. */
        if (av_fifo_realloc2(fpc->fifo_buf,
                             (read_end - read_start) + av_fifo_size(fpc->fifo_buf)) < 0) {
            av_log(avctx, AV_LOG_ERROR,
                   "couldn't reallocate buffer of size %td\n",
                   (read_end - read_start) + av_fifo_size(fpc->fifo_buf));
            goto handle_error;
        }

        if (buf) {
            av_fifo_generic_write(fpc->fifo_buf, (void*) read_start,
                                  read_end - read_start, NULL);
        } else {
            int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 };
            av_fifo_generic_write(fpc->fifo_buf, pad, sizeof(pad), NULL);
        }

        /* Tag headers and update sequences. */
        start_offset = av_fifo_size(fpc->fifo_buf) -
                       ((read_end - read_start) + (MAX_FRAME_HEADER_SIZE - 1));
        start_offset = FFMAX(0, start_offset);
        nb_headers   = find_new_headers(fpc, start_offset);

        if (nb_headers < 0) {
            av_log(avctx, AV_LOG_ERROR,
                   "find_new_headers couldn't allocate FLAC header\n");
            goto handle_error;
        }

        fpc->nb_headers_buffered = nb_headers;
        /* Wait till FLAC_MIN_HEADERS to output a valid frame. */
        if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) {
            if (buf && read_end < buf + buf_size) {
                read_start = read_end;
                continue;
            } else {
                goto handle_error;
            }
        }

        /* If headers found, update the scores since we have longer chains. */
        if (fpc->end_padded || fpc->nb_headers_found)
            score_sequences(fpc);

        /* restore the state pre-padding */
        if (fpc->end_padded) {
            /* HACK: drain the tail of the fifo */
            fpc->fifo_buf->wptr -= MAX_FRAME_HEADER_SIZE;
            fpc->fifo_buf->wndx -= MAX_FRAME_HEADER_SIZE;
            if (fpc->fifo_buf->wptr < 0) {
                fpc->fifo_buf->wptr += fpc->fifo_buf->end -
                    fpc->fifo_buf->buffer;
            }
            buf_size = 0;
            read_start = read_end = NULL;
        }
    }

    curr = fpc->headers;
    for (curr = fpc->headers; curr; curr = curr->next)
        if (!fpc->best_header || curr->max_score > fpc->best_header->max_score)
            fpc->best_header = curr;

    if (fpc->best_header) {
        fpc->best_header_valid = 1;
        if (fpc->best_header->offset > 0) {
            /* Output a junk frame. */
            av_log(avctx, AV_LOG_DEBUG, "Junk frame till offset %i\n",
                   fpc->best_header->offset);

            /* Set duration to 0. It is unknown or invalid in a junk frame. */
            s->duration = 0;
            *poutbuf_size     = fpc->best_header->offset;
            *poutbuf          = flac_fifo_read_wrap(fpc, 0, *poutbuf_size,
                                                    &fpc->wrap_buf,
                                                    &fpc->wrap_buf_allocated_size);
            return buf_size ? (read_end - buf) : (fpc->best_header->offset -
                                           av_fifo_size(fpc->fifo_buf));
        }
        if (!buf_size)
            return get_best_header(fpc, poutbuf, poutbuf_size);
    }

handle_error:
    *poutbuf      = NULL;
    *poutbuf_size = 0;
    return read_end - buf;
}
Ejemplo n.º 15
0
static void *start_smoothing( void *ptr )
{
    obe_t *h = ptr;
    int num_muxed_data = 0, buffer_complete = 0;
    int64_t start_clock = -1, start_pcr, end_pcr, temporal_vbv_size = 0, cur_pcr;
    obe_muxed_data_t **muxed_data = NULL, *start_data, *end_data;
    AVFifoBuffer *fifo_data = NULL, *fifo_pcr = NULL;
    uint8_t *output_buf;

    struct sched_param param = {0};
    param.sched_priority = 99;
    pthread_setschedparam( pthread_self(), SCHED_FIFO, &param );

    /* This thread buffers one VBV worth of frames */
    fifo_data = av_fifo_alloc( TS_PACKETS_SIZE );
    if( !fifo_data )
    {
        fprintf( stderr, "[mux-smoothing] Could not allocate data fifo" );
        return NULL;
    }

    fifo_pcr = av_fifo_alloc( 7 * sizeof(int64_t) );
    if( !fifo_pcr )
    {
        fprintf( stderr, "[mux-smoothing] Could not allocate pcr fifo" );
        return NULL;
    }

    if( h->obe_system == OBE_SYSTEM_TYPE_GENERIC )
    {
        for( int i = 0; i < h->num_encoders; i++ )
        {
            if( h->encoders[i]->is_video )
            {
                pthread_mutex_lock( &h->encoders[i]->queue.mutex );
                while( !h->encoders[i]->is_ready )
                    pthread_cond_wait( &h->encoders[i]->queue.in_cv, &h->encoders[i]->queue.mutex );
                x264_param_t *params = h->encoders[i]->encoder_params;
                temporal_vbv_size = av_rescale_q_rnd(
                (int64_t)params->rc.i_vbv_buffer_size * params->rc.f_vbv_buffer_init,
                (AVRational){1, params->rc.i_vbv_max_bitrate }, (AVRational){ 1, OBE_CLOCK }, AV_ROUND_UP );
                pthread_mutex_unlock( &h->encoders[i]->queue.mutex );
                break;
            }
        }
    }

    while( 1 )
    {
        pthread_mutex_lock( &h->mux_smoothing_queue.mutex );

        while( h->mux_smoothing_queue.size == num_muxed_data && !h->cancel_mux_smoothing_thread )
            pthread_cond_wait( &h->mux_smoothing_queue.in_cv, &h->mux_smoothing_queue.mutex );

        if( h->cancel_mux_smoothing_thread )
        {
            pthread_mutex_unlock( &h->mux_smoothing_queue.mutex );
            break;
        }

        num_muxed_data = h->mux_smoothing_queue.size;

        /* Refill the buffer after a drop */
        pthread_mutex_lock( &h->drop_mutex );
        if( h->mux_drop )
        {
            syslog( LOG_INFO, "Mux smoothing buffer reset\n" );
            h->mux_drop = 0;
            av_fifo_reset( fifo_data );
            av_fifo_reset( fifo_pcr );
            buffer_complete = 0;
            start_clock = -1;
        }
        pthread_mutex_unlock( &h->drop_mutex );

        if( !buffer_complete )
        {
            start_data = h->mux_smoothing_queue.queue[0];
            end_data = h->mux_smoothing_queue.queue[num_muxed_data-1];

            start_pcr = start_data->pcr_list[0];
            end_pcr = end_data->pcr_list[(end_data->len / 188)-1];
            if( end_pcr - start_pcr >= temporal_vbv_size )
            {
                buffer_complete = 1;
                start_clock = -1;
            }
            else
            {
                pthread_mutex_unlock( &h->mux_smoothing_queue.mutex );
                continue;
            }
        }

        //printf("\n mux smoothed frames %i \n", num_muxed_data );

        muxed_data = malloc( num_muxed_data * sizeof(*muxed_data) );
        if( !muxed_data )
        {
            pthread_mutex_unlock( &h->output_queue.mutex );
            syslog( LOG_ERR, "Malloc failed\n" );
            return NULL;
        }
        memcpy( muxed_data, h->mux_smoothing_queue.queue, num_muxed_data * sizeof(*muxed_data) );
        pthread_mutex_unlock( &h->mux_smoothing_queue.mutex );

        for( int i = 0; i < num_muxed_data; i++ )
        {
            if( av_fifo_realloc2( fifo_data, av_fifo_size( fifo_data ) + muxed_data[i]->len ) < 0 )
            {
                syslog( LOG_ERR, "Malloc failed\n" );
                return NULL;
            }

            av_fifo_generic_write( fifo_data, muxed_data[i]->data, muxed_data[i]->len, NULL );

            if( av_fifo_realloc2( fifo_pcr, av_fifo_size( fifo_pcr ) + ((muxed_data[i]->len * sizeof(int64_t)) / 188) ) < 0 )
            {
                syslog( LOG_ERR, "Malloc failed\n" );
                return NULL;
            }

            av_fifo_generic_write( fifo_pcr, muxed_data[i]->pcr_list, (muxed_data[i]->len * sizeof(int64_t)) / 188, NULL );

            remove_from_queue( &h->mux_smoothing_queue );
            destroy_muxed_data( muxed_data[i] );
        }

        free( muxed_data );
        muxed_data = NULL;
        num_muxed_data = 0;

        while( av_fifo_size( fifo_data ) >= TS_PACKETS_SIZE )
        {
            output_buf = malloc( TS_PACKETS_SIZE + 7 * sizeof(int64_t) );
            if( !output_buf )
            {
                syslog( LOG_ERR, "Malloc failed\n" );
                return NULL;
            }
            av_fifo_generic_read( fifo_pcr, output_buf, 7 * sizeof(int64_t), NULL );
            av_fifo_generic_read( fifo_data, &output_buf[7 * sizeof(int64_t)], TS_PACKETS_SIZE, NULL );

            cur_pcr = AV_RN64( output_buf );

            if( start_clock != -1 )
            {
                sleep_input_clock( h, cur_pcr - start_pcr + start_clock );
            }

            if( start_clock == -1 )
            {
                start_clock = get_input_clock_in_mpeg_ticks( h );
                start_pcr = cur_pcr;
            }

            if( add_to_queue( &h->output_queue, output_buf ) < 0 )
                return NULL;
            output_buf = NULL;
        }
    }

    av_fifo_free( fifo_data );
    av_fifo_free( fifo_pcr );

    return NULL;
}
Ejemplo n.º 16
0
static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
                                   int *got_frame, AVPacket *avpkt)
{
    MediaCodecH264DecContext *s = avctx->priv_data;
    AVFrame *frame    = data;
    int ret;

    /* buffer the input packet */
    if (avpkt->size) {
        AVPacket input_pkt = { 0 };

        if (av_fifo_space(s->fifo) < sizeof(input_pkt)) {
            ret = av_fifo_realloc2(s->fifo,
                                   av_fifo_size(s->fifo) + sizeof(input_pkt));
            if (ret < 0)
                return ret;
        }

        ret = av_packet_ref(&input_pkt, avpkt);
        if (ret < 0)
            return ret;
        av_fifo_generic_write(s->fifo, &input_pkt, sizeof(input_pkt), NULL);
    }

    /* process buffered data */
    while (!*got_frame) {
        /* prepare the input data -- convert to Annex B if needed */
        if (s->filtered_pkt.size <= 0) {
            AVPacket input_pkt = { 0 };

            av_packet_unref(&s->filtered_pkt);

            /* no more data */
            if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
                return avpkt->size ? avpkt->size :
                    ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, avpkt);
            }

            av_fifo_generic_read(s->fifo, &input_pkt, sizeof(input_pkt), NULL);

            ret = av_bsf_send_packet(s->bsf, &input_pkt);
            if (ret < 0) {
                return ret;
            }

            ret = av_bsf_receive_packet(s->bsf, &s->filtered_pkt);
            if (ret == AVERROR(EAGAIN)) {
                goto done;
            }

            /* h264_mp4toannexb is used here and does not requires flushing */
            av_assert0(ret != AVERROR_EOF);

            if (ret < 0) {
                return ret;
            }
        }

        ret = mediacodec_process_data(avctx, frame, got_frame, &s->filtered_pkt);
        if (ret < 0)
            return ret;

        s->filtered_pkt.size -= ret;
        s->filtered_pkt.data += ret;
    }
done:
    return avpkt->size;
}
Ejemplo n.º 17
0
void av_fifo_realloc(AVFifoBuffer *f, unsigned int new_size) {
    av_fifo_realloc2(f, new_size);
}
Ejemplo n.º 18
0
int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter,
                                        AVFilterBufferRef *picref, int flags)
{
    BufferSourceContext *c = buffer_filter->priv;
    AVFilterLink *outlink = buffer_filter->outputs[0];
    AVFilterBufferRef *buf;
    int ret;

    if (!picref) {
        c->eof = 1;
        return 0;
    } else if (c->eof)
        return AVERROR(EINVAL);

    if (!av_fifo_space(c->fifo) &&
        (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
                                         sizeof(buf))) < 0)
        return ret;

    if (picref->video->w != c->w || picref->video->h != c->h || picref->format != c->pix_fmt) {
        AVFilterContext *scale = buffer_filter->outputs[0]->dst;
        AVFilterLink *link;
        char scale_param[1024];

        av_log(buffer_filter, AV_LOG_INFO,
               "Buffer video input changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
               c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name,
               picref->video->w, picref->video->h, av_pix_fmt_descriptors[picref->format].name);

        if (!scale || strcmp(scale->filter->name, "scale")) {
            AVFilter *f = avfilter_get_by_name("scale");

            av_log(buffer_filter, AV_LOG_INFO, "Inserting scaler filter\n");
            if ((ret = avfilter_open(&scale, f, "Input equalizer")) < 0)
                return ret;

            c->scale = scale;

            snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s", c->w, c->h, c->sws_param);
            if ((ret = avfilter_init_filter(scale, scale_param, NULL)) < 0) {
                return ret;
            }

            if ((ret = avfilter_insert_filter(buffer_filter->outputs[0], scale, 0, 0)) < 0) {
                return ret;
            }
            scale->outputs[0]->time_base = scale->inputs[0]->time_base;

            scale->outputs[0]->format= c->pix_fmt;
        } else if (!strcmp(scale->filter->name, "scale")) {
            snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s",
                     scale->outputs[0]->w, scale->outputs[0]->h, c->sws_param);
            scale->filter->init(scale, scale_param, NULL);
        }

        c->pix_fmt = scale->inputs[0]->format = picref->format;
        c->w       = scale->inputs[0]->w      = picref->video->w;
        c->h       = scale->inputs[0]->h      = picref->video->h;

        link = scale->outputs[0];
        if ((ret =  link->srcpad->config_props(link)) < 0)
            return ret;
    }

    buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
                                    picref->video->w, picref->video->h);
    av_image_copy(buf->data, buf->linesize,
                  (void*)picref->data, picref->linesize,
                  picref->format, picref->video->w, picref->video->h);
    avfilter_copy_buffer_ref_props(buf, picref);

    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
        avfilter_unref_buffer(buf);
        return ret;
    }

    return 0;
}
Ejemplo n.º 19
0
static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
                                           AVFrame *frame, int flags)
{
    BufferSourceContext *s = ctx->priv;
    AVFrame *copy;
    int refcounted, ret;

    s->nb_failed_requests = 0;

    if (!frame) {
        s->eof = 1;
        return 0;
    } else if (s->eof)
        return AVERROR(EINVAL);

    refcounted = !!frame->buf[0];

    if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) {

    switch (ctx->outputs[0]->type) {
    case AVMEDIA_TYPE_VIDEO:
        CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height,
                                 frame->format);
        break;
    case AVMEDIA_TYPE_AUDIO:
        /* For layouts unknown on input but known on link after negotiation. */
        if (!frame->channel_layout)
            frame->channel_layout = s->channel_layout;
        CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout,
                                 av_frame_get_channels(frame), frame->format);
        break;
    default:
        return AVERROR(EINVAL);
    }

    }

    if (!av_fifo_space(s->fifo) &&
        (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
                                         sizeof(copy))) < 0)
        return ret;

    if (!(copy = av_frame_alloc()))
        return AVERROR(ENOMEM);

    if (refcounted) {
        av_frame_move_ref(copy, frame);
    } else {
        ret = av_frame_ref(copy, frame);
        if (ret < 0) {
            av_frame_free(&copy);
            return ret;
        }
    }

    if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
        if (refcounted)
            av_frame_move_ref(frame, copy);
        av_frame_free(&copy);
        return ret;
    }

    if ((flags & AV_BUFFERSRC_FLAG_PUSH))
        if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0)
            return ret;

    return 0;
}
Ejemplo n.º 20
0
static void *start_encoder( void *ptr )
{
    obe_aud_enc_params_t *enc_params = ptr;
    obe_t *h = enc_params->h;
    obe_encoder_t *encoder = enc_params->encoder;
    obe_output_stream_t *stream = enc_params->stream;
    obe_raw_frame_t *raw_frame;
    obe_coded_frame_t *coded_frame;
    void *audio_buf = NULL;
    int64_t cur_pts = -1, pts_increment;
    int i, frame_size, ret, got_pkt, num_frames = 0, total_size = 0, audio_buf_len;
    AVFifoBuffer *out_fifo = NULL;
    AVAudioResampleContext *avr = NULL;
    AVPacket pkt;
    AVCodecContext *codec = NULL;
    AVFrame *frame = NULL;
    AVDictionary *opts = NULL;
    char is_latm[2];

    avcodec_register_all();

    codec = avcodec_alloc_context3( NULL );
    if( !codec )
    {
        fprintf( stderr, "Malloc failed\n" );
        goto finish;
    }

    for( i = 0; lavc_encoders[i].obe_name != -1; i++ )
    {
        if( lavc_encoders[i].obe_name == stream->stream_format )
            break;
    }

    if( lavc_encoders[i].obe_name == -1 )
    {
        fprintf( stderr, "[lavc] Could not find encoder1\n" );
        goto finish;
    }

    AVCodec *enc = avcodec_find_encoder( lavc_encoders[i].lavc_name );
    if( !enc )
    {
        fprintf( stderr, "[lavc] Could not find encoder2\n" );
        goto finish;
    }

    if( enc->sample_fmts[0] == -1 )
    {
        fprintf( stderr, "[lavc] No valid sample formats\n" );
        goto finish;
    }

    codec->sample_rate = enc_params->sample_rate;
    codec->bit_rate = stream->bitrate * 1000;
    codec->sample_fmt = enc->sample_fmts[0];
    codec->channels = av_get_channel_layout_nb_channels( stream->channel_layout );
    codec->channel_layout = stream->channel_layout;
    codec->time_base.num = 1;
    codec->time_base.den = OBE_CLOCK;
    codec->profile = stream->aac_opts.aac_profile == AAC_HE_V2 ? FF_PROFILE_AAC_HE_V2 :
                     stream->aac_opts.aac_profile == AAC_HE_V1 ? FF_PROFILE_AAC_HE :
                     FF_PROFILE_AAC_LOW;

    snprintf( is_latm, sizeof(is_latm), "%i", stream->aac_opts.latm_output );
    av_dict_set( &opts, "latm", is_latm, 0 );
    av_dict_set( &opts, "header_period", "2", 0 );

    if( avcodec_open2( codec, enc, &opts ) < 0 )
    {
        fprintf( stderr, "[lavc] Could not open encoder\n" );
        goto finish;
    }

    avr = avresample_alloc_context();
    if( !avr )
    {
        fprintf( stderr, "Malloc failed\n" );
        goto finish;
    }

    av_opt_set_int( avr, "in_channel_layout",   codec->channel_layout, 0 );
    av_opt_set_int( avr, "in_sample_fmt",       enc_params->input_sample_format, 0 );
    av_opt_set_int( avr, "in_sample_rate",      enc_params->sample_rate, 0 );
    av_opt_set_int( avr, "out_channel_layout",  codec->channel_layout, 0 );
    av_opt_set_int( avr, "out_sample_fmt",      codec->sample_fmt,     0 );
    av_opt_set_int( avr, "dither_method",       AV_RESAMPLE_DITHER_TRIANGULAR_NS, 0 );

    if( avresample_open( avr ) < 0 )
    {
        fprintf( stderr, "Could not open AVResample\n" );
        goto finish;
    }

    /* The number of samples per E-AC3 frame is unknown until the encoder is ready */
    if( stream->stream_format == AUDIO_E_AC_3 || stream->stream_format == AUDIO_AAC )
    {
        pthread_mutex_lock( &encoder->queue.mutex );
        encoder->is_ready = 1;
        encoder->num_samples = codec->frame_size;
        /* Broadcast because input and muxer can be stuck waiting for encoder */
        pthread_cond_broadcast( &encoder->queue.in_cv );
        pthread_mutex_unlock( &encoder->queue.mutex );
    }

    frame_size = (double)codec->frame_size * 125 * stream->bitrate *
                 enc_params->frames_per_pes / enc_params->sample_rate;
    /* NB: libfdk-aac already doubles the frame size appropriately */
    pts_increment = (double)codec->frame_size * OBE_CLOCK * enc_params->frames_per_pes / enc_params->sample_rate;

    out_fifo = av_fifo_alloc( frame_size );
    if( !out_fifo )
    {
        fprintf( stderr, "Malloc failed\n" );
        goto finish;
    }

    audio_buf_len = codec->frame_size * av_get_bytes_per_sample( codec->sample_fmt ) * codec->channels;
    audio_buf = av_malloc( audio_buf_len );
    if( !audio_buf )
    {
        fprintf( stderr, "Malloc failed\n" );
        goto finish;
    }

    frame = avcodec_alloc_frame();
    if( !frame )
    {
        fprintf( stderr, "Could not allocate frame\n" );
        goto finish;
    }

    while( 1 )
    {
        /* TODO: detect bitrate or channel reconfig */
        pthread_mutex_lock( &encoder->queue.mutex );

        while( !encoder->queue.size && !encoder->cancel_thread )
            pthread_cond_wait( &encoder->queue.in_cv, &encoder->queue.mutex );

        if( encoder->cancel_thread )
        {
            pthread_mutex_unlock( &encoder->queue.mutex );
            goto finish;
        }

        raw_frame = encoder->queue.queue[0];
        pthread_mutex_unlock( &encoder->queue.mutex );

        if( cur_pts == -1 )
            cur_pts = raw_frame->pts;

        if( avresample_convert( avr, NULL, 0, raw_frame->audio_frame.num_samples, raw_frame->audio_frame.audio_data,
                                raw_frame->audio_frame.linesize, raw_frame->audio_frame.num_samples ) < 0 )
        {
            syslog( LOG_ERR, "[lavc] Sample format conversion failed\n" );
            break;
        }

        raw_frame->release_data( raw_frame );
        raw_frame->release_frame( raw_frame );
        remove_from_queue( &encoder->queue );

        while( avresample_available( avr ) >= codec->frame_size )
        {
            got_pkt = 0;
            avcodec_get_frame_defaults( frame );
            frame->nb_samples = codec->frame_size;
            avresample_read( avr, &audio_buf, codec->frame_size );

            if( avcodec_fill_audio_frame( frame, codec->channels, codec->sample_fmt, audio_buf, audio_buf_len, 0 ) < 0 )
            {
                syslog( LOG_ERR, "[lavc] Could not fill audio frame\n" );
                break;
            }

            av_init_packet( &pkt );
            pkt.data = NULL;
            pkt.size = 0;

            ret = avcodec_encode_audio2( codec, &pkt, frame, &got_pkt );
            if( ret < 0 )
            {
                syslog( LOG_ERR, "[lavc] Audio encoding failed\n" );
                goto finish;
            }

            if( !got_pkt )
                continue;

            total_size += pkt.size;
            num_frames++;

            if( av_fifo_realloc2( out_fifo, av_fifo_size( out_fifo ) + pkt.size ) < 0 )
            {
                syslog( LOG_ERR, "Malloc failed\n" );
                break;
            }

            av_fifo_generic_write( out_fifo, pkt.data, pkt.size, NULL );
            obe_free_packet( &pkt );

            if( num_frames == enc_params->frames_per_pes )
            {
                coded_frame = new_coded_frame( encoder->output_stream_id, total_size );
                if( !coded_frame )
                {
                    syslog( LOG_ERR, "Malloc failed\n" );
                    goto finish;
                }

                av_fifo_generic_read( out_fifo, coded_frame->data, total_size, NULL );

                coded_frame->pts = cur_pts;
                coded_frame->random_access = 1; /* Every frame output is a random access point */
                add_to_queue( &h->mux_queue, coded_frame );

                /* We need to generate PTS because frame sizes have changed */
                cur_pts += pts_increment;
                total_size = num_frames = 0;
            }
        }
    }

finish:
    if( frame )
       avcodec_free_frame( &frame );

    if( audio_buf )
        av_free( audio_buf );

    if( out_fifo )
        av_fifo_free( out_fifo );

    if( avr )
        avresample_free( &avr );

    if( codec )
    {
        avcodec_close( codec );
        av_free( codec );
    }

    free( enc_params );

    return NULL;
}