static void enc_postprocess(MSFilter *f) {
	EncData *d=(EncData*)f->data;
	rfc3984_destroy(d->packer);
	AMediaCodec_flush(d->codec);
	AMediaCodec_stop(d->codec);
	d->packer=NULL;
}
void mylooper::handle(int what, void *obj)
{
   switch (what)
   {
      case kMsgCodecBuffer:
         doCodecWork((workerdata *) obj);
         break;

      case kMsgDecodeDone:
      {
         workerdata *d = (workerdata *) obj;
         AMediaCodec_stop(d->codec);
         AMediaCodec_delete(d->codec);
         AMediaExtractor_delete(d->ex);
         d->sawInputEOS = true;
         d->sawOutputEOS = true;
      }
         break;

      case kMsgSeek:
      {
         workerdata *d = (workerdata *) obj;
         AMediaExtractor_seekTo(d->ex, 0, AMEDIAEXTRACTOR_SEEK_NEXT_SYNC);
         AMediaCodec_flush(d->codec);
         d->renderstart = -1;
         d->sawInputEOS = false;
         d->sawOutputEOS = false;
         d->isPlaying = true;
         post(kMsgCodecBuffer, d);
      }
         break;

      case kMsgPause:
      {
         workerdata *d = (workerdata *) obj;
         if (d->isPlaying)
         {
            // flush all outstanding codecbuffer messages with a no-op message
            d->isPlaying = false;
            post(kMsgPauseAck, NULL, true);
         }
      }
         break;

      case kMsgResume:
      {
         workerdata *d = (workerdata *) obj;
         if (!d->isPlaying)
         {
            d->renderstart = -1;
            d->isPlaying = true;
            post(kMsgCodecBuffer, d);
         }
      }
         break;
   }
}
Exemple #3
0
static GF_Err MCDec_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID)
{
    MCDec *ctx = (MCDec *)ifcg->privateStack;
    
    if(AMediaCodec_stop(ctx->codec) != AMEDIA_OK) {
         GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC,("AMediaCodec_stop failed"));
    }
    MCDec_DeleteSurface();

    return GF_OK;
}
static void dec_uninit(MSFilter *f){
	DecData *d=(DecData*)f->data;
	rfc3984_uninit(&d->unpacker);
	AMediaCodec_stop(d->codec);
    AMediaCodec_delete(d->codec);

	if (d->sps) freemsg(d->sps);
	if (d->pps) freemsg(d->pps);
	ms_free(d->bitstream);
	ms_yuv_buf_allocator_free(d->buf_allocator);
	ms_free(d);
}
static void dec_reinit(DecData *d){
	AMediaFormat *format;
	AMediaCodec_flush(d->codec);
	AMediaCodec_stop(d->codec);
    AMediaCodec_delete(d->codec);

	ms_message("Restart dec");

	d->codec = AMediaCodec_createDecoderByType("video/avc");
	format = AMediaFormat_new();
	AMediaFormat_setString(format,"mime","video/avc");
	//Size mandatory for decoder configuration
	AMediaFormat_setInt32(format,"width",1920);
	AMediaFormat_setInt32(format,"height",1080);

	AMediaCodec_configure(d->codec, format, NULL, NULL, 0);
	AMediaCodec_start(d->codec);
	AMediaFormat_delete(format);
}
static void enc_uninit(MSFilter *f){
	EncData *d=(EncData*)f->data;
	AMediaCodec_stop(d->codec);
    AMediaCodec_delete(d->codec);
	ms_free(d);
}
Exemple #7
0
static GF_Err MCDec_ProcessData(GF_MediaDecoder *ifcg,
                               char *inBuffer, u32 inBufferLength,
                               u16 ES_ID, u32 *CTS,
                               char *outBuffer, u32 *outBufferLength,
                               u8 PaddingBits, u32 mmlevel)
{
    MCDec *ctx = (MCDec *)ifcg->privateStack;
	ctx->nalu_size_length = 0;
	Bool mcdec_buffer_available = GF_FALSE;
	if (!ctx->reconfig_needed)
		MCDec_ParseNALs(ctx, inBuffer, inBufferLength, NULL, NULL);
	
	if (ctx->reconfig_needed) {
		if (ctx->raw_frame_dispatch && ctx->decoded_frames_pending) {
			*outBufferLength = 1;
			return GF_BUFFER_TOO_SMALL;
		}
		
		if (ctx->codec) {
			AMediaCodec_flush(ctx->codec);
			AMediaCodec_stop(ctx->codec);
			AMediaCodec_delete(ctx->codec);
			ctx->codec = NULL;
		}
		MCDec_InitDecoder(ctx);
			 if (ctx->out_size != *outBufferLength) {
				 *outBufferLength = ctx->out_size;
				 return GF_BUFFER_TOO_SMALL;
			 }
	}
	
	if(!ctx->inputEOS) {
		ssize_t inIndex = AMediaCodec_dequeueInputBuffer(ctx->codec,ctx->dequeue_timeout);
		
		if (inIndex >= 0) {

            size_t inSize;
            char *buffer = (char *)AMediaCodec_getInputBuffer(ctx->codec, inIndex, &inSize);

            if (inBufferLength > inSize)  {
                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC,("The returned buffer is too small"));
                return GF_BUFFER_TOO_SMALL;
            }

        switch (ctx->esd->decoderConfig->objectTypeIndication) {

            case GPAC_OTI_VIDEO_AVC:
					memcpy(buffer, inBuffer, inBufferLength);
					break;


            case GPAC_OTI_VIDEO_HEVC:

                if(inBuffer[4] == 0x40) { //check for vps
                    u32 start = ctx->vps_size + ctx->sps_size + ctx->pps_size;
                    u32 i;
                                    
                    for (i = start; i < inBufferLength ; ++i) {
                        buffer[i - start] = inBuffer[i];
                    }
					buffer[0] = 0x00;
					buffer[1] = 0x00;
					buffer[2] = 0x00;
					buffer[3] = 0x01;
                }
                else {
                    memcpy(buffer, inBuffer, inBufferLength);
                }
				
				break;

           default:
                memcpy(buffer, inBuffer, inBufferLength);
                break;
        }

            if(!inBuffer || inBufferLength == 0){
                 GF_LOG(GF_LOG_INFO, GF_LOG_CODEC,("AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM input"));
				 ctx->inputEOS = GF_TRUE;
            }
			if(AMediaCodec_queueInputBuffer(ctx->codec,
                                    inIndex,
                                    0, 
                                    inBufferLength,
                                    *CTS,
                                    inBuffer ? 0 : AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM
                ) != AMEDIA_OK)
                {
                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC,("AMediaCodec_queueInputBuffer failed"));
                return GF_BAD_PARAM;
            }
            mcdec_buffer_available = GF_TRUE;
        }
    }

    if(!ctx->outputEOS) {
		
       
        ctx->outIndex = AMediaCodec_dequeueOutputBuffer(ctx->codec, &ctx->info, ctx->dequeue_timeout);
        *outBufferLength=0;
        
        switch(ctx->outIndex) {
	    case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED:
                GF_LOG(GF_LOG_INFO, GF_LOG_CODEC,("AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED"));
                ctx->format = AMediaCodec_getOutputFormat(ctx->codec);
                break;

            case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
                GF_LOG(GF_LOG_INFO, GF_LOG_CODEC,("AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED"));
                break;

            case AMEDIACODEC_INFO_TRY_AGAIN_LATER:
                GF_LOG(GF_LOG_INFO, GF_LOG_CODEC,("AMEDIACODEC_INFO_TRY_AGAIN_LATER"));
                break;

            default:
				if (ctx->outIndex >= 0) {
					*CTS = ctx->info.presentationTimeUs;
					if(ctx->info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
						 GF_LOG(GF_LOG_INFO, GF_LOG_CODEC,("AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM output"));
						ctx->outputEOS = true;
					}
					 
					if(!ctx->surface_rendering) {
						size_t outSize;
						uint8_t * buffer = AMediaCodec_getOutputBuffer(ctx->codec, ctx->outIndex, &outSize);
						ctx->frame = buffer + ctx->info.offset;
						
						if(!ctx->frame) {
							 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC,("AMediaCodec_getOutputBuffer failed"));
							*outBufferLength = 0;
						}
					}
					
					if(ctx->surface_rendering || ctx->frame) {
						if(ctx->info.size < ctx->out_size)
						*outBufferLength = ctx->info.size;
						else *outBufferLength = ctx->out_size;
					}
				}
			break;
			
			}

    }
	
	return (mcdec_buffer_available) ? GF_OK : GF_CODEC_BUFFER_UNAVAILABLE;      
}