Beispiel #1
0
GF_EXPORT
u32 gf_ringbuffer_read(GF_Ringbuffer *rb, u8 *dest, u32 szDest)
{
 u32 free_sz, sz2, to_read, n1, n2;

  if ((free_sz = gf_ringbuffer_available_for_read(rb)) == 0) {
    return 0;
  }

  to_read = szDest > free_sz ? free_sz : szDest;

  sz2 = rb->read_ptr + to_read;

  if (sz2 > rb->size) {
    n1 = rb->size - rb->read_ptr;
    n2 = sz2 & rb->size_mask;
  } else {
    n1 = to_read;
    n2 = 0;
  }

  memcpy (dest, &(rb->buf[rb->read_ptr]), n1);
  rb->read_ptr += n1;
  rb->read_ptr &= rb->size_mask;

  if (n2) {
    memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2);
    rb->read_ptr += n2;
    rb->read_ptr &= rb->size_mask;
  }

  return to_read; 
}
Beispiel #2
0
/**
 * This thread sends the frame to TS mux
 * \param Parameter The GF_AVRedirect pointer
 */
static Bool audio_encoding_thread_run(void *param)
{
    u8 * inBuff;
    u8 * outBuff;
    u32 inBuffSize, outBuffSize, samplesReaden, toRead;
    u64 myTime = 0;
    u32 frameCountSinceReset = 0;
    u32 lastCurrentTime;
    Bool sendPts = 1;
    GF_AVRedirect * avr = (GF_AVRedirect*) param;
    AVCodecContext * ctx = NULL;
    assert( avr );

	outBuffSize = FF_MIN_BUFFER_SIZE;

    outBuff = gf_malloc(outBuffSize* sizeof(u8));
    inBuff = NULL;
#ifdef DUMP_MP3
    FILE * mp3 = fopen("/tmp/dump.mp3", "w");
#endif /* DUMP_MP3 */
    sendPts = 1;
    gf_sc_add_audio_listener ( avr->term->compositor, &avr->audio_listen );
    while (avr->is_running && !ctx) {
        ctx = ts_get_audio_codec_context(avr->ts_implementation);
        gf_sleep(16);
    }
    if (!ctx) {
        goto exit;
    }

    printf("******* Audio Codec Context = %d/%d, start="LLU", frame_size=%u\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start, ctx->frame_size);
    samplesReaden = ctx->frame_size * ctx->channels;

    //printf("SETUP input sample size=%u, output samplesize=%u, buffsize=%u, samplesReaden=%u\n", ctx->input_sample_size, ctx->frame_size, sizeof(outbuf), samplesReaden);
    // 2 chars are needed for each short
    toRead = samplesReaden * 2;
    inBuffSize = toRead;
    inBuff = gf_malloc(inBuffSize * sizeof(u8));
    while (avr->is_running && !avr->audioCurrentTime) {
        gf_sleep(16);
    }
    myTime = lastCurrentTime = avr->audioCurrentTime;
    frameCountSinceReset = 0;
    while (avr->is_running) {
        u32 readen;
        if (U32_ABS(avr->audioCurrentTime, myTime) > 25000) {
            //GF_LOG( GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] Drift in audio : audioCurrentTime = %u, myTime=%u, resync...\n", avr->audioCurrentTime, myTime));
            //myTime = lastCurrentTime = avr->audioCurrentTime;
            //frameCountSinceReset = 0;
            sendPts = 1;
        }
        while (toRead <= gf_ringbuffer_available_for_read(avr->pcmAudio) ) {
            memset( inBuff, 0, inBuffSize);
            memset( outBuff, 0, outBuffSize);
            readen = gf_ringbuffer_read(avr->pcmAudio, inBuff, toRead);
            assert( readen == toRead );
            if (avr->encode)
            {
                //u32 oldFrameSize = ctx->frame_size;
                //ctx->frame_size = readable / (2 * ctx->channels);
                //assert( oldFrameSize <= ctx->frame_size );
                /* buf_size * input_sample_size / output_sample_size */
                int encoded = avcodec_encode_audio(ctx, outBuff, outBuffSize, (const short *) inBuff);
                if (encoded < 0) {
                    GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[RedirectAV]: failed to encode audio, buffer size=%u, readen=%u, frame_size=%u\n", outBuffSize, readen, ctx->frame_size));
                } else if (encoded > 0) {
                    ts_encode_audio_frame(avr->ts_implementation, outBuff, encoded, sendPts ? myTime : AV_NOPTS_VALUE );
                    frameCountSinceReset++;
#ifdef DUMP_MP3
                    fwrite( outBuff, sizeof(char), encoded, mp3);
#endif /* DUMP_MP3 */
                    //if (ctx->codec->id == CODEC_ID_MP3) {
                    /* It seems the MP3 codec only fetches 50% of data... */
                    //    myTime= lastCurrentTime + (frameCountSinceReset * ctx->frame_size * 500 / ctx->sample_rate);
                    //} else
                    //myTime = lastCurrentTime + (frameCountSinceReset * toRead * 1000 / ctx->sample_rate/ ctx->channels / 4);
                    /* Avoid overflow , multiply by 10 and divide sample rate by 100 instead of  *1000 / sampleRate */
                    myTime = lastCurrentTime + (frameCountSinceReset * toRead * 10 / (ctx->sample_rate / 100) / ctx->channels / 4);
                    //sendPts = 0;
                    sendPts = 1;
                } else {
                    GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[RedirectAV]: no encoded frame.\n"));
                    //frameCountSinceReset++;
                }
                //ctx->frame_size = oldFrameSize;
            }
        }
		gf_sleep(1);
    }
exit:
    GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending audio encoding thread...\n"));
    if (inBuff)
        gf_free( inBuff );
    if (outBuff)
        gf_free( outBuff );
#ifdef DUMP_MP3
    if (mp3)
        fclose(mp3);
#endif /* DUMP_MP3 */
    if (avr->term)
        gf_sc_remove_audio_listener ( avr->term->compositor, &avr->audio_listen );
    return GF_OK;
}