Exemplo n.º 1
0
static int seek_test(const char *input_filename, const char *start, const char *end)
{
    AVCodec *codec = NULL;
    AVCodecContext *ctx= NULL;
    AVCodecParameters *origin_par = NULL;
    AVFrame *fr = NULL;
    AVFormatContext *fmt_ctx = NULL;
    int video_stream;
    int result;
    int i, j;
    long int start_ts, end_ts;

    size_of_array = 0;
    number_of_elements = 0;
    crc_array = pts_array = NULL;

    result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL);
    if (result < 0) {
        av_log(NULL, AV_LOG_ERROR, "Can't open file\n");
        return result;
    }

    result = avformat_find_stream_info(fmt_ctx, NULL);
    if (result < 0) {
        av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n");
        return result;
    }

    start_ts = read_seek_range(start);
    end_ts = read_seek_range(end);
    if ((start_ts < 0) || (end_ts < 0))
        return -1;

    //TODO: add ability to work with audio format
    video_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
    if (video_stream < 0) {
        av_log(NULL, AV_LOG_ERROR, "Can't find video stream in input file\n");
        return -1;
    }

    origin_par = fmt_ctx->streams[video_stream]->codecpar;

    codec = avcodec_find_decoder(origin_par->codec_id);
    if (!codec) {
        av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n");
        return -1;
    }

    ctx = avcodec_alloc_context3(codec);
    if (!ctx) {
        av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n");
        return AVERROR(ENOMEM);
    }

    result = avcodec_parameters_to_context(ctx, origin_par);
    if (result) {
        av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n");
        return result;
    }

    result = avcodec_open2(ctx, codec, NULL);
    if (result < 0) {
        av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n");
        return result;
    }

    fr = av_frame_alloc();
    if (!fr) {
        av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n");
        return AVERROR(ENOMEM);
    }

    result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, fr, i, j, 1);
    if (result != 0)
        return -1;

    for (i = start_ts; i < end_ts; i += 100) {
        for (j = i + 100; j < end_ts; j += 100)
            result = compute_crc_of_packets(fmt_ctx, video_stream, ctx, fr, i, j, 0);
        if (result != 0)
            return -1;
    }

    av_freep(&crc_array);
    av_freep(&pts_array);
    av_frame_free(&fr);
    avcodec_close(ctx);
    avformat_close_input(&fmt_ctx);
    avcodec_free_context(&ctx);
    return 0;
}
Exemplo n.º 2
0
int stream_component_open(VideoState *is, int stream_index) {

  AVFormatContext *pFormatCtx = is->pFormatCtx;
  AVCodecContext *codecCtx = NULL;
  AVCodec *codec = NULL;
  AVDictionary *optionsDict = NULL;

  if(stream_index < 0 || stream_index >= pFormatCtx->nb_streams) {
    return -1;
  }

  // Get a pointer to the codec context for the video stream
  codecCtx = pFormatCtx->streams[stream_index]->codec;

  if(codecCtx->codec_type == AVMEDIA_TYPE_AUDIO) {
	is->audio_callback = audio_callback;

    // Set audio settings from codec info
	AudioPlayer *player = malloc(sizeof(AudioPlayer));
    is->audio_player = player;
    createEngine(&is->audio_player);
    createBufferQueueAudioPlayer(&is->audio_player, is, codecCtx->channels, codecCtx->sample_rate);
    //is->audio_hw_buf_size = 4096;
  } else if (codecCtx->codec_type == AVMEDIA_TYPE_VIDEO) {
	// Set video settings from codec info
	VideoPlayer *player = malloc(sizeof(VideoPlayer));
	is->video_player = player;
	createVideoEngine(&is->video_player);
  }
  codec = avcodec_find_decoder(codecCtx->codec_id);
  if(!codec || (avcodec_open2(codecCtx, codec, &optionsDict) < 0)) {
    fprintf(stderr, "Unsupported codec!\n");
    return -1;
  }

  switch(codecCtx->codec_type) {
  case AVMEDIA_TYPE_AUDIO:
    is->audioStream = stream_index;
    is->audio_st = pFormatCtx->streams[stream_index];
    is->audio_buf_size = 0;
    is->audio_buf_index = 0;

    /* averaging filter for audio sync */
    is->audio_diff_avg_coef = exp(log(0.01 / AUDIO_DIFF_AVG_NB));
    is->audio_diff_avg_count = 0;
    /* Correct audio only if larger error than this */
    is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / codecCtx->sample_rate;

	is->sws_ctx_audio = swr_alloc();
	if (!is->sws_ctx_audio) {
		fprintf(stderr, "Could not allocate resampler context\n");
		return -1;
	}

    memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
    packet_queue_init(&is->audioq);
    break;
  case AVMEDIA_TYPE_VIDEO:
    is->videoStream = stream_index;
    is->video_st = pFormatCtx->streams[stream_index];

    is->frame_timer = (double)av_gettime() / 1000000.0;
    is->frame_last_delay = 40e-3;
    is->video_current_pts_time = av_gettime();

    packet_queue_init(&is->videoq);
    is->video_tid = malloc(sizeof(*(is->video_tid)));
	// uncomment for video
    pthread_create(is->video_tid, NULL, (void *) &video_thread, is);
    is->sws_ctx =
        sws_getContext
        (
            is->video_st->codec->width,
            is->video_st->codec->height,
            is->video_st->codec->pix_fmt,
            is->video_st->codec->width,
            is->video_st->codec->height,
            AV_PIX_FMT_YUV420P,
            SWS_BILINEAR,
            NULL,
            NULL,
            NULL
        );

    /*is->sws_ctx =
    	sws_getContext
    	(
    		is->video_st->codec->width,
    		is->video_st->codec->height,
    		is->video_st->codec->pix_fmt,
    		//pCodecCtx->width,
    		//pCodecCtx->height,
    		is->video_st->codec->width,
    		is->video_st->codec->height,
    		TARGET_IMAGE_FORMAT,
    	    SWS_BILINEAR,
    	    NULL,
    	    NULL,
    	    NULL
    	);*/

    codecCtx->get_buffer2 = our_get_buffer;

    break;
  default:
    break;
  }

  return 0;
}
Exemplo n.º 3
0
static int startffmpeg(struct anim *anim)
{
	int i, videoStream;

	AVCodec *pCodec;
	AVFormatContext *pFormatCtx = NULL;
	AVCodecContext *pCodecCtx;
	AVRational frame_rate;
	int frs_num;
	double frs_den;
	int streamcount;

#ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
	/* The following for color space determination */
	int srcRange, dstRange, brightness, contrast, saturation;
	int *table;
	const int *inv_table;
#endif

	if (anim == NULL) return(-1);

	streamcount = anim->streamindex;

	if (avformat_open_input(&pFormatCtx, anim->name, NULL, NULL) != 0) {
		return -1;
	}

	if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
		avformat_close_input(&pFormatCtx);
		return -1;
	}

	av_dump_format(pFormatCtx, 0, anim->name, 0);


	/* Find the video stream */
	videoStream = -1;

	for (i = 0; i < pFormatCtx->nb_streams; i++)
		if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
			if (streamcount > 0) {
				streamcount--;
				continue;
			}
			videoStream = i;
			break;
		}

	if (videoStream == -1) {
		avformat_close_input(&pFormatCtx);
		return -1;
	}

	pCodecCtx = pFormatCtx->streams[videoStream]->codec;

	/* Find the decoder for the video stream */
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	if (pCodec == NULL) {
		avformat_close_input(&pFormatCtx);
		return -1;
	}

	pCodecCtx->workaround_bugs = 1;

	if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
		avformat_close_input(&pFormatCtx);
		return -1;
	}
	if (pCodecCtx->pix_fmt == AV_PIX_FMT_NONE) {
		avcodec_close(anim->pCodecCtx);
		avformat_close_input(&pFormatCtx);
		return -1;
	}

	frame_rate = av_get_r_frame_rate_compat(pFormatCtx, pFormatCtx->streams[videoStream]);
	if (pFormatCtx->streams[videoStream]->nb_frames != 0) {
		anim->duration = pFormatCtx->streams[videoStream]->nb_frames;
	}
	else {
		anim->duration = (int)(pFormatCtx->duration *
		                       av_q2d(frame_rate) /
		                       AV_TIME_BASE + 0.5f);
	}

	frs_num = frame_rate.num;
	frs_den = frame_rate.den;

	frs_den *= AV_TIME_BASE;

	while (frs_num % 10 == 0 && frs_den >= 2.0 && frs_num > 10) {
		frs_num /= 10;
		frs_den /= 10;
	}

	anim->frs_sec = frs_num;
	anim->frs_sec_base = frs_den;

	anim->params = 0;

	anim->x = pCodecCtx->width;
	anim->y = av_get_cropped_height_from_codec(pCodecCtx);

	anim->pFormatCtx = pFormatCtx;
	anim->pCodecCtx = pCodecCtx;
	anim->pCodec = pCodec;
	anim->videoStream = videoStream;

	anim->interlacing = 0;
	anim->orientation = 0;
	anim->framesize = anim->x * anim->y * 4;

	anim->curposition = -1;
	anim->last_frame = 0;
	anim->last_pts = -1;
	anim->next_pts = -1;
	anim->next_packet.stream_index = -1;

	anim->pFrame = av_frame_alloc();
	anim->pFrameComplete = false;
	anim->pFrameDeinterlaced = av_frame_alloc();
	anim->pFrameRGB = av_frame_alloc();

	if (need_aligned_ffmpeg_buffer(anim)) {
		anim->pFrameRGB->format = AV_PIX_FMT_RGBA;
		anim->pFrameRGB->width  = anim->x;
		anim->pFrameRGB->height = anim->y;

		if (av_frame_get_buffer(anim->pFrameRGB, 32) < 0) {
			fprintf(stderr, "Could not allocate frame data.\n");
			avcodec_close(anim->pCodecCtx);
			avformat_close_input(&anim->pFormatCtx);
			av_frame_free(&anim->pFrameRGB);
			av_frame_free(&anim->pFrameDeinterlaced);
			av_frame_free(&anim->pFrame);
			anim->pCodecCtx = NULL;
			return -1;
		}
	}

	if (avpicture_get_size(AV_PIX_FMT_RGBA, anim->x, anim->y) !=
	    anim->x * anim->y * 4)
	{
		fprintf(stderr,
		        "ffmpeg has changed alloc scheme ... ARGHHH!\n");
		avcodec_close(anim->pCodecCtx);
		avformat_close_input(&anim->pFormatCtx);
		av_frame_free(&anim->pFrameRGB);
		av_frame_free(&anim->pFrameDeinterlaced);
		av_frame_free(&anim->pFrame);
		anim->pCodecCtx = NULL;
		return -1;
	}

	if (anim->ib_flags & IB_animdeinterlace) {
		avpicture_fill((AVPicture *) anim->pFrameDeinterlaced,
		               MEM_callocN(avpicture_get_size(
		                               anim->pCodecCtx->pix_fmt,
		                               anim->pCodecCtx->width,
		                               anim->pCodecCtx->height),
		                           "ffmpeg deinterlace"),
		               anim->pCodecCtx->pix_fmt, 
		               anim->pCodecCtx->width,
		               anim->pCodecCtx->height);
	}

	if (pCodecCtx->has_b_frames) {
		anim->preseek = 25; /* FIXME: detect gopsize ... */
	}
	else {
		anim->preseek = 0;
	}
	
	anim->img_convert_ctx = sws_getContext(
	        anim->x,
	        anim->y,
	        anim->pCodecCtx->pix_fmt,
	        anim->x,
	        anim->y,
	        AV_PIX_FMT_RGBA,
	        SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
	        NULL, NULL, NULL);
		
	if (!anim->img_convert_ctx) {
		fprintf(stderr,
		        "Can't transform color space??? Bailing out...\n");
		avcodec_close(anim->pCodecCtx);
		avformat_close_input(&anim->pFormatCtx);
		av_frame_free(&anim->pFrameRGB);
		av_frame_free(&anim->pFrameDeinterlaced);
		av_frame_free(&anim->pFrame);
		anim->pCodecCtx = NULL;
		return -1;
	}

#ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
	/* Try do detect if input has 0-255 YCbCR range (JFIF Jpeg MotionJpeg) */
	if (!sws_getColorspaceDetails(anim->img_convert_ctx, (int **)&inv_table, &srcRange,
	                              &table, &dstRange, &brightness, &contrast, &saturation))
	{
		srcRange = srcRange || anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG;
		inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace);

		if (sws_setColorspaceDetails(anim->img_convert_ctx, (int *)inv_table, srcRange,
		                             table, dstRange, brightness, contrast, saturation))
		{
			fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
		}
	}
	else {
		fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
	}
#endif
		
	return (0);
}
Exemplo n.º 4
0
bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
{
  AVCodec* pCodec = avcodec_find_decoder(hints.codec);
  if (!pCodec)
  {
    CLog::Log(LOGDEBUG,"%s - Unable to find codec %d", __FUNCTION__, hints.codec);
    return false;
  }

  m_pCodecContext = avcodec_alloc_context3(pCodec);
  m_pCodecContext->debug_mv = 0;
  m_pCodecContext->debug = 0;
  m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT;
  m_pCodecContext->codec_tag = hints.codec_tag;
  m_pCodecContext->time_base.num = 1;
  m_pCodecContext->time_base.den = DVD_TIME_BASE;
  m_pCodecContext->pkt_timebase.num = 1;
  m_pCodecContext->pkt_timebase.den = DVD_TIME_BASE;

  if( hints.extradata && hints.extrasize > 0 )
  {
    m_pCodecContext->extradata_size = hints.extrasize;
    m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE);
    memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);

    // start parsing of extra data - create a copy to be safe and make it zero-terminating to avoid access violations!
    unsigned int parse_extrasize = hints.extrasize;
    char* parse_extra = new char[parse_extrasize + 1];
    memcpy(parse_extra, hints.extradata, parse_extrasize);
    parse_extra[parse_extrasize] = '\0';

    // assume that the extra data is formatted as a concatenation of lines ('\n' terminated) 
    char *ptr = parse_extra;
    do // read line by line
    {
      if (!strncmp(ptr, "size:", 5))
      {
        int width = 0, height = 0;
        sscanf(ptr, "size: %dx%d", &width, &height);
        if (width > 0 && height > 0)
        {
          m_pCodecContext->width = width;
          m_pCodecContext->height = height;
          CLog::Log(LOGDEBUG,"%s - parsed extradata: size: %d x %d", __FUNCTION__,  width, height);
        }
      }
      /*        
      // leaving commented code: these items don't work yet... but they may be meaningful
      if (!strncmp(ptr, "palette:", 8))
        if (sscanf(ptr, "palette: %x, %x, %x, %x, %x, %x, %x, %x,"
                                " %x, %x, %x, %x, %x, %x, %x, %x", ...        
      if (!strncasecmp(ptr, "forced subs: on", 15))
        forced_subs_only = 1;
      */
      // if tried all possibilities, then read newline char and move to next line
      ptr = strchr(ptr, '\n');
      if (ptr != NULL) ptr++;
    } 
    while (ptr != NULL && ptr <= parse_extra + parse_extrasize);

    delete[] parse_extra;
  }

  if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
  {
    CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec");
    return false;
  }

  return true;
}
Exemplo n.º 5
0
std::string get_codec_name(AVCodecContext *pCodecCtx)
{
  AVCodecID id = pCodecCtx->codec_id;

  // Grab the codec
  const AVCodec *p = avcodec_find_decoder(id);
  const AVCodecDescriptor *desc = avcodec_descriptor_get(id);
  const char *profile = avcodec_profile_name(id, pCodecCtx->profile);

  std::ostringstream codec_name;

  const char *nice_name = nullptr;
  for (int i = 0; i < countof(nice_codec_names); ++i)
  {
    if (nice_codec_names[i].id == id) {
      nice_name = nice_codec_names[i].name;
      break;
    }
  }

  if (id == AV_CODEC_ID_DTS && pCodecCtx->codec_tag == 0xA2) {
    profile = "DTS Express";
  }

  if (id == AV_CODEC_ID_H264 && profile) {
    codec_name << nice_name << " " << tolower(profile);
    if (pCodecCtx->level && pCodecCtx->level != FF_LEVEL_UNKNOWN && pCodecCtx->level < 1000) {
      char l_buf[5];
      sprintf_s(l_buf, "%.1f", pCodecCtx->level / 10.0);
      codec_name << " L" << l_buf;
    }
  } else if (id == AV_CODEC_ID_VC1 && profile) {
    codec_name << nice_name << " " << tolower(profile);
    if (pCodecCtx->level != FF_LEVEL_UNKNOWN) {
      codec_name << " L" << pCodecCtx->level;
    }
  } else if (id == AV_CODEC_ID_DTS && profile) {
    codec_name << tolower(profile);
  } else if (id == AV_CODEC_ID_JPEG2000 && profile) {
    codec_name << tolower(profile);
  } else if (nice_name) {
    codec_name << nice_name;
    if (profile)
      codec_name << " " << tolower(profile);
  } else if (desc && desc->name) {
    codec_name << desc->name;
    if (profile)
      codec_name << " " << tolower(profile);
  } else if (p && p->name) {
    codec_name << p->name;
    if (profile)
      codec_name << " " << tolower(profile);
  } else {
    /* output avi tags */
    char buf[32];
    av_get_codec_tag_string(buf, sizeof(buf), pCodecCtx->codec_tag);
    codec_name << buf;
    sprintf_s(buf, "0x%04X", pCodecCtx->codec_tag);
    codec_name  << " / " << buf;
  }
  return codec_name.str();
}
void Utility::VideoLoader::loadP() {
	isRunning_=true;
	target_->setIsComplete(false);
	// Contains information about the stream
	AVFormatContext *formatContext = NULL;

	// Contains information about the codex
	AVCodecContext *codecContext = NULL;

	// The coder with wich to decode the video
	AVCodec *codec = NULL;

	// Open video file
	// avformat_open_input(context, path, format, options)
	// format = NULL means autodetect
	if(!path_.isEmpty()
	        && avformat_open_input(&formatContext, path_.toUtf8(), NULL, NULL)!=0) {
		target_->setIsComplete(true);
		return;
	}

	// Retrieve stream information
	if(avformat_find_stream_info(formatContext, NULL)<0) {
		target_->setIsComplete(true);
		return;
	}

	// Print stream information
	// av_dump_format(formatContext, 0, path_.toUtf8(), 0);


	// Find the best video stream in context
	int videoStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
	if(videoStreamIndex == -1) {
		target_->setIsComplete(true);
		return;
	}

	// Get a pointer to the codec context for the video stream
	codecContext = formatContext->streams[videoStreamIndex]->codec;

	// Find the decoder for the video stream
	codec = avcodec_find_decoder(codecContext->codec_id);
	if(codec == NULL) {
		target_->setIsComplete(true);
		return;
	}

	// Open codec
	if(avcodec_open2(codecContext, codec, &dict_) < 0) {
		target_->setIsComplete(true);
		return;
	}

	struct SwsContext      *sws_ctx = NULL;

	averageBitrate_=codecContext->bit_rate;
	codec_=QString(av_codec_get_codec_descriptor(codecContext)->name);
	if(codec_=="")
		codec_="N/A";

	sws_ctx =
	    sws_getContext
	    (
	        codecContext->width,
	        codecContext->height,
	        codecContext->pix_fmt,
	        codecContext->width,
	        codecContext->height,
	        AV_PIX_FMT_RGB24,
	        0,
	        0,
	        0,
	        0
	    );

	AVPacket packet;
	AVFrame *frame = NULL;
	frame = av_frame_alloc();

	AVFrame* rgbframe=NULL;
	uint8_t* buffer = NULL;
	int numbytes=avpicture_get_size(AV_PIX_FMT_RGB24, codecContext->width,codecContext->height);

	target_->setFps(codecContext->framerate.num);
	av_init_packet(&packet);
	packet.data = NULL;
	packet.size = 0;
	int gotPicture = 0;
	while(av_read_frame(formatContext, &packet) >= 0&&isRunning_) {
		avcodec_decode_video2(codecContext, frame, &gotPicture, &packet);

		if(gotPicture != 0) {
			rgbframe=av_frame_alloc();

			buffer=(uint8_t *)av_malloc(numbytes*sizeof(uint8_t));
			avpicture_fill((AVPicture *)rgbframe, buffer, AV_PIX_FMT_RGB24,codecContext->width,
			               codecContext->height);
			rgbframe->width=codecContext->width;
			rgbframe->height=codecContext->height;
			rgbframe->format=AV_PIX_FMT_RGB24;
			rgbframe->pkt_size=frame->pkt_size;

			sws_scale
			(
			    sws_ctx,
			    frame->data,
			    frame->linesize,
			    0,
			    codecContext->height,
			    rgbframe->data,
			    rgbframe->linesize
			);

			target_->appendFrame(rgbframe);
		}
	}

	packet.data=NULL;
	packet.size=0;

	while(isRunning_) {
		avcodec_decode_video2(codecContext, frame, &gotPicture, &packet);

		if(gotPicture == 0)
			break;

		rgbframe=av_frame_alloc();

		buffer=(uint8_t *)av_malloc(numbytes*sizeof(uint8_t));
		avpicture_fill((AVPicture *)rgbframe, buffer, AV_PIX_FMT_RGB24,codecContext->width,
		               codecContext->height);
		rgbframe->width=codecContext->width;
		rgbframe->height=codecContext->height;
		rgbframe->format=AV_PIX_FMT_RGB24;
		rgbframe->pkt_size=frame->pkt_size;

		sws_scale
		(
		    sws_ctx,
		    frame->data,
		    frame->linesize,
		    0,
		    codecContext->height,
		    rgbframe->data,
		    rgbframe->linesize
		);

		target_->appendFrame(rgbframe);
	}
	av_frame_unref(frame);
	av_frame_free(&frame);
	avcodec_close(codecContext);
	avformat_close_input(&formatContext);
	isRunning_=false;
	if(dict_) {
		free(dict_);
	}
	target_->setIsComplete(true);
}
Exemplo n.º 7
0
/*
 * Audio decoding.
 */
static void audio_decode_example(const char *outfilename, const char *filename)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    int len;
    FILE *f, *outfile;
    uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
    AVPacket avpkt;
    AVFrame *decoded_frame = NULL;

    av_init_packet(&avpkt);

    printf("Audio decoding\n");

    /* find the mpeg audio decoder */
    codec = avcodec_find_decoder(CODEC_ID_MP2);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);

    /* open it */
    if (avcodec_open2(c, codec, NULL) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    f = fopen(filename, "rb");
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }
    outfile = fopen(outfilename, "wb");
    if (!outfile) {
        av_free(c);
        exit(1);
    }

    /* decode until eof */
    avpkt.data = inbuf;
    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);

    while (avpkt.size > 0) {
        int got_frame = 0;

        if (!decoded_frame) {
            if (!(decoded_frame = avcodec_alloc_frame())) {
                fprintf(stderr, "out of memory\n");
                exit(1);
            }
        } else
            avcodec_get_frame_defaults(decoded_frame);

        len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
        if (len < 0) {
            fprintf(stderr, "Error while decoding\n");
            exit(1);
        }
        if (got_frame) {
            /* if a frame has been decoded, output it */
            int data_size = av_samples_get_buffer_size(NULL, c->channels,
                                                       decoded_frame->nb_samples,
                                                       c->sample_fmt, 1);
            fwrite(decoded_frame->data[0], 1, data_size, outfile);
        }
        avpkt.size -= len;
        avpkt.data += len;
        if (avpkt.size < AUDIO_REFILL_THRESH) {
            /* Refill the input buffer, to avoid trying to decode
             * incomplete frames. Instead of this, one could also use
             * a parser, or use a proper container format through
             * libavformat. */
            memmove(inbuf, avpkt.data, avpkt.size);
            avpkt.data = inbuf;
            len = fread(avpkt.data + avpkt.size, 1,
                        AUDIO_INBUF_SIZE - avpkt.size, f);
            if (len > 0)
                avpkt.size += len;
        }
    }

    fclose(outfile);
    fclose(f);

    avcodec_close(c);
    av_free(c);
    av_free(decoded_frame);
}
Exemplo n.º 8
0
int stream_component_open(VideoState *is, int stream_index) {

    AVFormatContext *pFormatCtx = is->pFormatCtx;
    AVCodecContext *codecCtx = NULL;
    AVCodec *codec = NULL;
    AVDictionary *optionsDict = NULL;
    SDL_AudioSpec wanted_spec, spec;

    if (stream_index < 0 || stream_index >= pFormatCtx->nb_streams) {
        return -1;
    }

    // Get a pointer to the codec context for the video stream
    codecCtx = pFormatCtx->streams[stream_index]->codec;

    if (codecCtx->codec_type == AVMEDIA_TYPE_AUDIO) {
        // Set audio settings from codec info
        wanted_spec.freq = codecCtx->sample_rate;
        wanted_spec.format = AUDIO_S16SYS;
        wanted_spec.channels = codecCtx->channels;
        wanted_spec.silence = 0;
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
        wanted_spec.callback = audio_callback;
        wanted_spec.userdata = is;

        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
            return -1;
        }
        is->audio_hw_buf_size = spec.size;
    }
    codec = avcodec_find_decoder(codecCtx->codec_id);
    if (!codec || (avcodec_open2(codecCtx, codec, &optionsDict) < 0)) {
        fprintf(stderr, "Unsupported codec!\n");
        return -1;
    }

    switch (codecCtx->codec_type) {
        case AVMEDIA_TYPE_AUDIO:
            is->audioStream = stream_index;
            is->audio_st = pFormatCtx->streams[stream_index];
            is->audio_buf_size = 0;
            is->audio_buf_index = 0;

            /* averaging filter for audio sync */
            is->audio_diff_avg_coef = exp(log(0.01 / AUDIO_DIFF_AVG_NB));
            is->audio_diff_avg_count = 0;
            /* Correct audio only if larger error than this */
            is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / codecCtx->sample_rate;

            memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
            packet_queue_init(&is->audioq);
            SDL_PauseAudio(0);
            break;
        case AVMEDIA_TYPE_VIDEO:
            is->videoStream = stream_index;
            is->video_st = pFormatCtx->streams[stream_index];

            is->frame_timer = (double) av_gettime() / 1000000.0;
            is->frame_last_delay = 40e-3;
            is->video_current_pts_time = av_gettime();

            packet_queue_init(&is->videoq);
            is->video_tid = SDL_CreateThread(video_thread, is);
            is->sws_ctx =
                    sws_getContext
                            (
                                    is->video_st->codec->width,
                                    is->video_st->codec->height,
                                    is->video_st->codec->pix_fmt,
                                    is->video_st->codec->width,
                                    is->video_st->codec->height,
                                    PIX_FMT_YUV420P,
                                    SWS_BILINEAR,
                                    NULL,
                                    NULL,
                                    NULL
                            );
            codecCtx->get_buffer2 = our_get_buffer;
            codecCtx->release_buffer = our_release_buffer;
            break;
        default:
            break;
    }

    return 0;
}
Exemplo n.º 9
0
int RemoteCameraRtsp::PrimeCapture()
{
    Debug( 2, "Waiting for sources" );
    for ( int i = 0; i < 100 && !rtspThread->hasSources(); i++ )
    {
        usleep( 100000 );
    }
    if ( !rtspThread->hasSources() )
        Fatal( "No RTSP sources" );

    Debug( 2, "Got sources" );

    mFormatContext = rtspThread->getFormatContext();

    // Find first video stream present
    mVideoStreamId = -1;
    
    for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ )
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51,2,1)
	if ( mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
#else
	if ( mFormatContext->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
#endif
        {
            mVideoStreamId = i;
            break;
        }
    if ( mVideoStreamId == -1 )
        Fatal( "Unable to locate video stream" );

    // Get a pointer to the codec context for the video stream
    mCodecContext = mFormatContext->streams[mVideoStreamId]->codec;

    // Find the decoder for the video stream
    mCodec = avcodec_find_decoder( mCodecContext->codec_id );
    if ( mCodec == NULL )
        Panic( "Unable to locate codec %d decoder", mCodecContext->codec_id );

    // Open codec
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 7, 0)
    if ( avcodec_open( mCodecContext, mCodec ) < 0 )
#else
    if ( avcodec_open2( mCodecContext, mCodec, 0 ) < 0 )
#endif
        Panic( "Can't open codec" );

    // Allocate space for the native video frame
    mRawFrame = avcodec_alloc_frame();

    // Allocate space for the converted video frame
    mFrame = avcodec_alloc_frame();
    
	if(mRawFrame == NULL || mFrame == NULL)
		Fatal( "Unable to allocate frame(s)");
	
	int pSize = avpicture_get_size( imagePixFormat, width, height );
	if( (unsigned int)pSize != imagesize) {
		Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
	}
/*	
#if HAVE_LIBSWSCALE
	if(!sws_isSupportedInput(mCodecContext->pix_fmt)) {
		Fatal("swscale does not support the codec format: %c%c%c%c",(mCodecContext->pix_fmt)&0xff,((mCodecContext->pix_fmt>>8)&0xff),((mCodecContext->pix_fmt>>16)&0xff),((mCodecContext->pix_fmt>>24)&0xff));
	}

	if(!sws_isSupportedOutput(imagePixFormat)) {
		Fatal("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff));
	}
	
#else // HAVE_LIBSWSCALE
    Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" );
#endif // HAVE_LIBSWSCALE
*/

    return( 0 );
}
Exemplo n.º 10
0
Libav::Libav(std::string filename, int st, int streamNumber) throw (AVException*)
{

	pictureBuffer = NULL;
	pFrame = NULL;
	
	this->setIn(-1);
	this->setOut(-1);
	
	// default sane values
	this->setFrameRateNum(1);
	this->setFrameRateDen(1);
	this->setSampleAspectNum(1);
	this->setSampleAspectDen(1);
	
	pFormatCtx = NULL;
	
	frameCounter = 0;
	avStream = -1;
	streamType = st;
	
	lavFileName =std::string(filename);
	
	av_register_all();

	if (this->openInputFile(filename) < 0)
	{
		throw new AVException("Failed to open file: " + filename, IO_ERROR);
		// std::cerr<<"initWithFile: avformat_open_input failed to open: "<<filename << "\n";
		// how do I deal with constructor errors.
	}

	if(this->findStreamInfo()<0)
	{
		throw new AVException("Failed to find stream info", FILE_ERROR);

		//std::cerr<<"initWithFile: avformat_find_stream_info failed\n";
		// another constructor error.
	}
    
    //
    
   // this->initMeta(fmt_ctx);
    
    this->initMeta(pFormatCtx);

    
	if ((avStream = this->findStream(streamNumber,streamType)) == -1) {
        std::stringstream exception;
        exception << "couldn't find requested AV stream: " << streamNumber;

		throw new AVException(exception.str(), FILE_ERROR);

		//std::cerr<<"initWithFile: couldn't find requested AV stream\n";
		// constructor error blah blah
	}

	// std::cerr << "Chosen stream: " << avStream << "\n";
	
	pCodecCtx = pFormatCtx->streams[avStream]->codec;
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	
    
    // this is a hack to work around the unsupported S16P
    if (pCodecCtx->sample_fmt == AV_SAMPLE_FMT_S16P)
        pCodecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16;

    
	// open codec context
	if (this->openAVCodec() < 0)
	{
		throw new AVException("Could not find or open codec", FILE_ERROR);

		//std::cerr<<"initWithFile: could not find or open codec\n";
	 // Could not open codec
	}
	
//	std::cerr << filename << " pframe addr: " << pFrame << "\n";
	
	pFrame=avcodec_alloc_frame();
	
//	std::cerr << filename << " pframe addr: " << pFrame << "\n";

	
	//std::cerr<<"framerate: " << pFormatCtx->streams[avStream]->r_frame_rate.num <<":" <<pFormatCtx->streams[avStream]->r_frame_rate.den << "\n";
	//std::cerr<<"dar: " << pCodecCtx->sample_aspect_ratio.num <<":" <<pCodecCtx->sample_aspect_ratio.den << "\n";

	this->setFrameRate(pFormatCtx->streams[avStream]->r_frame_rate);
	this->setSampleAspect(pCodecCtx->sample_aspect_ratio);
	
//	std::cerr<<"chroma: " << pCodecCtx->pix_fmt << "\n";
	
	this->setChromaSampling(pCodecCtx->pix_fmt);
	this->setHeight(pCodecCtx->height);
	this->setWidth(pCodecCtx->width);
	this->setSampleFormat(pCodecCtx->sample_fmt);
	this->setSampleChannels(pCodecCtx->channels);
}
Exemplo n.º 11
0
static void
audio_process_audio(audio_decoder_t *ad, media_buf_t *mb)
{
  const audio_class_t *ac = ad->ad_ac;
  AVFrame *frame = ad->ad_frame;
  media_pipe_t *mp = ad->ad_mp;
  media_queue_t *mq = &mp->mp_audio;
  int r;
  int got_frame;
  AVPacket avpkt;
  int offset = 0;

  if(mb->mb_skip || mb->mb_stream != mq->mq_stream) 
    return;

  while(offset < mb->mb_size) {

    if(mb->mb_cw == NULL) {
      frame->sample_rate = mb->mb_rate;
      frame->format = AV_SAMPLE_FMT_S16;
      switch(mb->mb_channels) {
      case 1:
	frame->channel_layout = AV_CH_LAYOUT_MONO;
	frame->nb_samples = mb->mb_size / 2;
	break;
      case 2:
	frame->channel_layout = AV_CH_LAYOUT_STEREO;
	frame->nb_samples = mb->mb_size / 4;
	break;
      default:
	abort();
      }
      frame->data[0] = mb->mb_data;
      frame->linesize[0] = 0;
      r = mb->mb_size;
      got_frame = 1;

    } else {

      media_codec_t *mc = mb->mb_cw;

      AVCodecContext *ctx = mc->ctx;

      if(mc->codec_id != ad->ad_in_codec_id) {
	AVCodec *codec = avcodec_find_decoder(mc->codec_id);
	TRACE(TRACE_DEBUG, "audio", "Codec changed to %s",
	      codec ? codec->name : "???");
	ad->ad_in_codec_id = mc->codec_id;

	audio_cleanup_spdif_muxer(ad);
  
	if(ac->ac_check_passthru != NULL && codec != NULL &&
	   ac->ac_check_passthru(ad, mc->codec_id)) {

	  audio_setup_spdif_muxer(ad, codec, mq);
	}
      }

      av_init_packet(&avpkt);
      avpkt.data = mb->mb_data + offset;
      avpkt.size = mb->mb_size - offset;

      if(ad->ad_spdif_muxer != NULL) {
	av_write_frame(ad->ad_spdif_muxer, &avpkt);
	avio_flush(ad->ad_spdif_muxer->pb);
	ad->ad_pts = mb->mb_pts;
	ad->ad_epoch = mb->mb_epoch;
	return;
      }

      if(ctx == NULL) {

	AVCodec *codec = avcodec_find_decoder(mc->codec_id);
	assert(codec != NULL); // Checked in libav.c

	ctx = mc->ctx = avcodec_alloc_context3(codec);

	if(ad->ad_stereo_downmix)
	  ctx->request_channels = 2;

	if(avcodec_open2(mc->ctx, codec, NULL) < 0) {
	  av_freep(&mc->ctx);
	  return;
	}
      }

      r = avcodec_decode_audio4(ctx, frame, &got_frame, &avpkt);
      if(r < 0)
	return;

      if(frame->sample_rate == 0) {
	frame->sample_rate = ctx->sample_rate;

	if(frame->sample_rate == 0 && mb->mb_cw->fmt_ctx)
	  frame->sample_rate = mb->mb_cw->fmt_ctx->sample_rate;
    
	if(frame->sample_rate == 0)
	  return;
      }

      if(frame->channel_layout == 0) {
	switch(ctx->channels) {
	case 1:
	  frame->channel_layout = AV_CH_LAYOUT_MONO;
	  break;
	case 2:
	  frame->channel_layout = AV_CH_LAYOUT_STEREO;
	  break;
	default:
	  return;
	}
      }

      if(mp->mp_stats)
	mp_set_mq_meta(mq, ctx->codec, ctx);

    }

    if(offset == 0 && mb->mb_pts != AV_NOPTS_VALUE) {
        
      int od = 0, id = 0;
          
      if(ad->ad_avr != NULL) {
	od = avresample_available(ad->ad_avr) *
	  1000000LL / ad->ad_out_sample_rate;
	id = avresample_get_delay(ad->ad_avr) *
	  1000000LL / frame->sample_rate;
      }
      ad->ad_pts = mb->mb_pts - od - id;
      ad->ad_epoch = mb->mb_epoch;
      //        printf("od=%-20d id=%-20d PTS=%-20ld oPTS=%-20ld\n",
      // od, id, mb->mb_pts, pts);
        
      if(mb->mb_drive_clock)
	mp_set_current_time(mp, mb->mb_pts - ad->ad_delay,
			    mb->mb_epoch, mb->mb_delta);
    }

    offset += r;

    if(got_frame) {

      if(frame->sample_rate    != ad->ad_in_sample_rate ||
	 frame->format         != ad->ad_in_sample_format ||
	 frame->channel_layout != ad->ad_in_channel_layout) {
          
	ad->ad_in_sample_rate    = frame->sample_rate;
	ad->ad_in_sample_format  = frame->format;
	ad->ad_in_channel_layout = frame->channel_layout;

	ac->ac_reconfig(ad);

	if(ad->ad_avr == NULL)
	  ad->ad_avr = avresample_alloc_context();
	else
	  avresample_close(ad->ad_avr);
          
	av_opt_set_int(ad->ad_avr, "in_sample_fmt",
		       ad->ad_in_sample_format, 0);
	av_opt_set_int(ad->ad_avr, "in_sample_rate", 
		       ad->ad_in_sample_rate, 0);
	av_opt_set_int(ad->ad_avr, "in_channel_layout",
		       ad->ad_in_channel_layout, 0);

	av_opt_set_int(ad->ad_avr, "out_sample_fmt",
		       ad->ad_out_sample_format, 0);
	av_opt_set_int(ad->ad_avr, "out_sample_rate",
		       ad->ad_out_sample_rate, 0);
	av_opt_set_int(ad->ad_avr, "out_channel_layout",
		       ad->ad_out_channel_layout, 0);
          
	char buf1[128];
	char buf2[128];

	av_get_channel_layout_string(buf1, sizeof(buf1), 
				     -1, ad->ad_in_channel_layout);
	av_get_channel_layout_string(buf2, sizeof(buf2), 
				     -1, ad->ad_out_channel_layout);

	TRACE(TRACE_DEBUG, "Audio",
	      "Converting from [%s %dHz %s] to [%s %dHz %s]",
	      buf1, ad->ad_in_sample_rate,
	      av_get_sample_fmt_name(ad->ad_in_sample_format),
	      buf2, ad->ad_out_sample_rate,
	      av_get_sample_fmt_name(ad->ad_out_sample_format));

	if(avresample_open(ad->ad_avr)) {
	  TRACE(TRACE_ERROR, "AudioQueue", "Unable to open resampler");
	  avresample_free(&ad->ad_avr);
	}

	if(ac->ac_set_volume != NULL) {
	  prop_set(mp->mp_prop_ctrl, "canAdjustVolume", PROP_SET_INT, 1);
	  ac->ac_set_volume(ad, ad->ad_vol_scale);
	}
      }
      if(ad->ad_avr != NULL)
	avresample_convert(ad->ad_avr, NULL, 0, 0,
			   frame->data, frame->linesize[0],
			   frame->nb_samples);
    }
  }
}
Exemplo n.º 12
0
status_t
AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer,
	size_t infoSize)
{
	if (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO
		&& ioEncodedFormat->type != B_MEDIA_ENCODED_VIDEO)
		return B_ERROR;

	fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO);
	TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v'));

#ifdef TRACE_AV_CODEC
	char buffer[1024];
	string_for_format(*ioEncodedFormat, buffer, sizeof(buffer));
	TRACE("[%c]   input_format = %s\n", fIsAudio?('a'):('v'), buffer);
	TRACE("[%c]   infoSize = %ld\n", fIsAudio?('a'):('v'), infoSize);
	TRACE("[%c]   user_data_type = %08lx\n", fIsAudio?('a'):('v'),
		ioEncodedFormat->user_data_type);
	TRACE("[%c]   meta_data_size = %ld\n", fIsAudio?('a'):('v'),
		ioEncodedFormat->MetaDataSize());
#endif

	media_format_description description;
	if (BMediaFormats().GetCodeFor(*ioEncodedFormat,
			B_MISC_FORMAT_FAMILY, &description) == B_OK) {
		if (description.u.misc.file_format != 'ffmp')
			return B_NOT_SUPPORTED;
		fCodec = avcodec_find_decoder(static_cast<CodecID>(
			description.u.misc.codec));
		if (fCodec == NULL) {
			TRACE("  unable to find the correct FFmpeg "
				"decoder (id = %lu)\n", description.u.misc.codec);
			return B_ERROR;
		}
		TRACE("  found decoder %s\n", fCodec->name);

		const void* extraData = infoBuffer;
		fExtraDataSize = infoSize;
		if (description.family == B_WAV_FORMAT_FAMILY
				&& infoSize >= sizeof(wave_format_ex)) {
			TRACE("  trying to use wave_format_ex\n");
			// Special case extra data in B_WAV_FORMAT_FAMILY
			const wave_format_ex* waveFormatData
				= (const wave_format_ex*)infoBuffer;

			size_t waveFormatSize = infoSize;
			if (waveFormatData != NULL && waveFormatSize > 0) {
				fBlockAlign = waveFormatData->block_align;
				TRACE("  found block align: %d\n", fBlockAlign);
				fExtraDataSize = waveFormatData->extra_size;
				// skip the wave_format_ex from the extra data.
				extraData = waveFormatData + 1;
			}
		} else {
			if (fIsAudio) {
				fBlockAlign
					= ioEncodedFormat->u.encoded_audio.output
						.buffer_size;
				TRACE("  using buffer_size as block align: %d\n",
					fBlockAlign);
			}
		}
		if (extraData != NULL && fExtraDataSize > 0) {
			TRACE("AVCodecDecoder: extra data size %ld\n", infoSize);
			delete[] fExtraData;
			fExtraData = new(std::nothrow) char[fExtraDataSize];
			if (fExtraData != NULL)
				memcpy(fExtraData, infoBuffer, fExtraDataSize);
			else
				fExtraDataSize = 0;
		}

		fInputFormat = *ioEncodedFormat;
		return B_OK;
	} else {
		TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n");
	}

	printf("AVCodecDecoder::Setup failed!\n");
	return B_ERROR;
}
Exemplo n.º 13
0
ARCODECS_Manager_FFMPEGDecoder_t *ARCODECS_Manager_NewFFMPEGDecoder (eARCODECS_ERROR *error)
{
    /* -- Create a new FFMPEG decoder -- */
    ARCODECS_Manager_FFMPEGDecoder_t *ffmpegDecoder = NULL;
    eARCODECS_ERROR localError = ARCODECS_OK;
    
    ffmpegDecoder = calloc (1, sizeof(ARCODECS_Manager_FFMPEGDecoder_t));
    if (ffmpegDecoder == NULL)
    {
        localError = ARCODECS_ERROR_ALLOC;
    }
    /* No else: the FFMPEG Decoder is successfully allocated and initialized to "0" */
    if (localError == ARCODECS_OK)
    {
        /* register all the codecs */
        avcodec_register_all();
        
        //av_log_set_level(AV_LOG_WARNING);
        av_log_set_level(AV_LOG_QUIET);
        
        /* get the H264 decoder */
        ffmpegDecoder->codec = avcodec_find_decoder (AV_CODEC_ID_H264);
        if(ffmpegDecoder->codec == NULL)
        {
            localError = ARCODECS_ERROR_MANAGER_UNSUPPORTED_CODEC;
        }
        /* No else: the codec is successfully found */
    }
    /* No else: skipped by an error */
    if(localError == ARCODECS_OK)
    {
        ffmpegDecoder->codecCtx = avcodec_alloc_context3(ffmpegDecoder->codec);
        if(ffmpegDecoder->codecCtx == NULL)
        {
            localError = ARCODECS_ERROR_ALLOC;
        }
        /* No else : the ffmpeg context is successfully allocated */
    }
    /* No else: skipped by an error */
    if(localError == ARCODECS_OK)
    {
        /* initialize the codec context */
        ffmpegDecoder->codecCtx->pix_fmt = PIX_FMT_YUV420P;
        //ffmpegDecoder->codecCtx->pix_fmt = PIX_FMT_BGR24;
        ffmpegDecoder->codecCtx->skip_frame = AVDISCARD_DEFAULT;
        ffmpegDecoder->codecCtx->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
        ffmpegDecoder->codecCtx->skip_loop_filter = AVDISCARD_DEFAULT;
        ffmpegDecoder->codecCtx->workaround_bugs = FF_BUG_AUTODETECT;
        ffmpegDecoder->codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
        ffmpegDecoder->codecCtx->codec_id = AV_CODEC_ID_H264;
        ffmpegDecoder->codecCtx->skip_idct = AVDISCARD_DEFAULT;
        
        if (avcodec_open2(ffmpegDecoder->codecCtx, ffmpegDecoder->codec, NULL) < 0)
        {
            localError = ARCODECS_ERROR_MANAGER_CODEC_OPENING;
        }
        /* No else: the codec is not open ; localError is set to ARCODECS_ERROR_MANAGER_CODEC_OPENING ; stops the processing */
    }
    /* No else: skipped by an error */
    if(localError == ARCODECS_OK)
    {
        ffmpegDecoder->decodedFrame = avcodec_alloc_frame();
        if (ffmpegDecoder->decodedFrame == NULL)
        {
            localError = ARCODECS_ERROR_ALLOC;
        }
        /* No else: the decodedFrame is not allocate ; localError is set to ARCODECS_ERROR_ALLOC ; stops the processing */
    }
    /* No else: skipped by an error */
    
    if(localError == ARCODECS_OK)
    {
        av_init_packet(&ffmpegDecoder->avpkt);
    }
    /* No else: skipped by an error */
    
    /* return error*/
    if(error != NULL)
    {
        *error = localError;
    }
    /* No else: the error is not returned */
    
    return ffmpegDecoder;
}
Exemplo n.º 14
0
int dc_audio_decoder_open(AudioInputFile *audio_input_file, AudioDataConf *audio_data_conf, int mode, int no_loop)
{
	u32 i;
	AVCodecContext *codec_ctx;
	AVCodec *codec;
	AVInputFormat *in_fmt = NULL;

	if (audio_data_conf->format && strcmp(audio_data_conf->format,"") != 0) {
		in_fmt = av_find_input_format(audio_data_conf->format);
		if (in_fmt == NULL) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find the format %s.\n", audio_data_conf->format));
			return -1;
		}
	}

	/*
	 * Open audio (may already be opened when shared with the video input).
	 */
	if (!audio_input_file->av_fmt_ctx) {
		if (avformat_open_input(&audio_input_file->av_fmt_ctx, audio_data_conf->filename, in_fmt, NULL) != 0) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open file: %s\n", audio_data_conf->filename));
			return -1;
		}

		/*
		* Retrieve stream information
		*/
		if (avformat_find_stream_info(audio_input_file->av_fmt_ctx, NULL) < 0) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find stream information\n"));
			return -1;
		}

		av_dump_format(audio_input_file->av_fmt_ctx, 0, audio_data_conf->filename, 0);
	}

	/*
	 * Find the first audio stream
	 */
	audio_input_file->astream_idx = -1;
	for (i=0; i<audio_input_file->av_fmt_ctx->nb_streams; i++) {
		if (audio_input_file->av_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
			audio_input_file->astream_idx = i;
			break;
		}
	}
	if (audio_input_file->astream_idx == -1) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find a audio stream\n"));
		return -1;
	}

	/*
	 * Get a pointer to the codec context for the audio stream
	 */
	codec_ctx = audio_input_file->av_fmt_ctx->streams[audio_input_file->astream_idx]->codec;

	/*
	 * Find the decoder for the audio stream
	 */
	codec = avcodec_find_decoder(codec_ctx->codec_id);
	if (codec == NULL) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Input audio codec is not supported.\n"));
		avformat_close_input(&audio_input_file->av_fmt_ctx);
		return -1;
	}

	/*
	 * Open codec
	 */
	if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input audio codec.\n"));
		avformat_close_input(&audio_input_file->av_fmt_ctx);
		return -1;
	}

#ifdef DC_AUDIO_RESAMPLER
	audio_input_file->aresampler = NULL;
#endif
	audio_input_file->fifo = av_fifo_alloc(2 * MAX_AUDIO_PACKET_SIZE);

	audio_data_conf->channels = codec_ctx->channels;
	audio_data_conf->samplerate = codec_ctx->sample_rate;

	audio_input_file->mode = mode;
	audio_input_file->no_loop = no_loop;

	return 0;
}
Exemplo n.º 15
0
int decode_audio_file(ChromaprintContext *chromaprint_ctx, int16_t *buffer1, int16_t *buffer2, const char *file_name, int max_length, int *duration)
{
	int i, ok = 0, remaining, length, consumed, buffer_size, codec_ctx_opened = 0;
	AVFormatContext *format_ctx = NULL;
	AVCodecContext *codec_ctx = NULL;
	AVCodec *codec = NULL;
	AVStream *stream = NULL;
	AVPacket packet, packet_temp;
#ifdef HAVE_AV_AUDIO_CONVERT
	AVAudioConvert *convert_ctx = NULL;
#endif
	int16_t *buffer;

#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
	if (av_open_input_file(&format_ctx, file_name, NULL, 0, NULL) != 0) {
#else
	if (avformat_open_input(&format_ctx, file_name, NULL, NULL) != 0) {
#endif
		fprintf(stderr, "ERROR: couldn't open the file\n");
		goto done;
	}

	if (av_find_stream_info(format_ctx) < 0) {
		fprintf(stderr, "ERROR: couldn't find stream information in the file\n");
		goto done;
	}

	for (i = 0; i < format_ctx->nb_streams; i++) {
		codec_ctx = format_ctx->streams[i]->codec;
		if (codec_ctx && codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
			stream = format_ctx->streams[i];
			break;
		}
	}
	if (!stream) {
		fprintf(stderr, "ERROR: couldn't find any audio stream in the file\n");
		goto done;
	}

	codec = avcodec_find_decoder(codec_ctx->codec_id);
	if (!codec) {
		fprintf(stderr, "ERROR: unknown codec\n");
		goto done;
	}

	if (avcodec_open(codec_ctx, codec) < 0) {
		fprintf(stderr, "ERROR: couldn't open the codec\n");
		goto done;
	}
	codec_ctx_opened = 1;

	if (codec_ctx->channels <= 0) {
		fprintf(stderr, "ERROR: no channels found in the audio stream\n");
		goto done;
	}

	if (codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16) {
#ifdef HAVE_AV_AUDIO_CONVERT
		convert_ctx = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, codec_ctx->channels,
		                                     codec_ctx->sample_fmt, codec_ctx->channels, NULL, 0);
		if (!convert_ctx) {
			fprintf(stderr, "ERROR: couldn't create sample format converter\n");
			goto done;
		}
#else
		fprintf(stderr, "ERROR: unsupported sample format\n");
		goto done;
#endif
	}

	*duration = stream->time_base.num * stream->duration / stream->time_base.den;

  if (max_length == 0) {
    max_length = duration;
  }

	av_init_packet(&packet);
	av_init_packet(&packet_temp);

	remaining = max_length * codec_ctx->channels * codec_ctx->sample_rate;
	chromaprint_start(chromaprint_ctx, codec_ctx->sample_rate, codec_ctx->channels);

	while (1) {
		if (av_read_frame(format_ctx, &packet) < 0) {
			break;
		}

		packet_temp.data = packet.data;
		packet_temp.size = packet.size;

		while (packet_temp.size > 0) {
			buffer_size = BUFFER_SIZE;
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 23, 0)
			consumed = avcodec_decode_audio2(codec_ctx,
				buffer1, &buffer_size, packet_temp.data, packet_temp.size);
#else
			consumed = avcodec_decode_audio3(codec_ctx,
				buffer1, &buffer_size, &packet_temp);
#endif

			if (consumed < 0) {
				break;
			}

			packet_temp.data += consumed;
			packet_temp.size -= consumed;

			if (buffer_size <= 0) {
				if (buffer_size < 0) {
					fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too small\n");
				}
				continue;
			}
			if (buffer_size > BUFFER_SIZE) {
				fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too large\n");
				continue;
			}

#ifdef HAVE_AV_AUDIO_CONVERT
			if (convert_ctx) {
				const void *ibuf[6] = { buffer1 };
				void *obuf[6] = { buffer2 };
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 8, 0)
				int istride[6] = { av_get_bits_per_sample_format(codec_ctx->sample_fmt) / 8 };
#else
				int istride[6] = { av_get_bytes_per_sample(codec_ctx->sample_fmt) };
#endif
				int ostride[6] = { 2 };
				int len = buffer_size / istride[0];
				if (av_audio_convert(convert_ctx, obuf, ostride, ibuf, istride, len) < 0) {
					break;
				}
				buffer = buffer2;
				buffer_size = len * ostride[0];
			}
			else {
				buffer = buffer1;
			}
#else
			buffer = buffer1;
#endif

			length = MIN(remaining, buffer_size / 2);
			if (!chromaprint_feed(chromaprint_ctx, buffer, length)) {
				fprintf(stderr, "ERROR: fingerprint calculation failed\n");
				goto done;
			}

			if (max_length) {
				remaining -= length;
				if (remaining <= 0) {
					goto finish;
				}
			}
		}

		if (packet.data) {
			av_free_packet(&packet);
		}
	}

finish:
	if (!chromaprint_finish(chromaprint_ctx)) {
		fprintf(stderr, "ERROR: fingerprint calculation failed\n");
		goto done;
	}

	ok = 1;

done:
	if (codec_ctx_opened) {
		avcodec_close(codec_ctx);
	}
	if (format_ctx) {
		av_close_input_file(format_ctx);
	}
#ifdef HAVE_AV_AUDIO_CONVERT
	if (convert_ctx) {
		av_audio_convert_free(convert_ctx);
	}
#endif
	return ok;
}

int fpcalc_main(int argc, char **argv)
{
	int i, j, max_length = 120, num_file_names = 0, raw = 0, raw_fingerprint_size, duration;
	int16_t *buffer1, *buffer2;
	int32_t *raw_fingerprint;
	char *file_name, *fingerprint, **file_names;
	ChromaprintContext *chromaprint_ctx;
	int algo = CHROMAPRINT_ALGORITHM_DEFAULT;

	file_names = malloc(argc * sizeof(char *));
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];
		if (!strcmp(arg, "-length") && i + 1 < argc) {
			max_length = atoi(argv[++i]);
		}
		else if (!strcmp(arg, "-version") || !strcmp(arg, "-v")) {
			printf("fpcalc version %s\n", chromaprint_get_version());
			return 0;
		}
		else if (!strcmp(arg, "-raw")) {
			raw = 1;
		}
		else if (!strcmp(arg, "-algo") && i + 1 < argc) {
			const char *v = argv[++i];
			if (!strcmp(v, "test1")) { algo = CHROMAPRINT_ALGORITHM_TEST1; }
			else if (!strcmp(v, "test2")) { algo = CHROMAPRINT_ALGORITHM_TEST2; }
			else if (!strcmp(v, "test3")) { algo = CHROMAPRINT_ALGORITHM_TEST3; }
			else if (!strcmp(v, "test4")) { algo = CHROMAPRINT_ALGORITHM_TEST4; }
			else {
				fprintf(stderr, "WARNING: unknown algorithm, using the default\n");
			}
		}
		else if (!strcmp(arg, "-set") && i + 1 < argc) {
      char *name = argv[++i];
      char *value = strchr(name, '=');
      if (!value && i + 1 < argc) {
        ++i;
      }
		}
		else {
			file_names[num_file_names++] = argv[i];
		}
	}

	if (!num_file_names) {
		printf("usage: %s [OPTIONS] FILE...\n\n", argv[0]);
		printf("Options:\n");
		printf("  -version      print version information\n");
		printf("  -length SECS  length of the audio data used for fingerprint calculation (default 120)\n");
		printf("  -raw          output the raw uncompressed fingerprint\n");
		printf("  -algo NAME    version of the fingerprint algorithm\n");
		return 2;
	}

	av_register_all();
	av_log_set_level(AV_LOG_ERROR);

	buffer1 = av_malloc(BUFFER_SIZE + 16);
	buffer2 = av_malloc(BUFFER_SIZE + 16);
	chromaprint_ctx = chromaprint_new(algo);

	for (i = 1; i < argc; i++) {
		char *arg = argv[i];
		if (!strcmp(arg, "-set") && i + 1 < argc) {
			char *name = argv[++i];
			char *value = strchr(name, '=');
			if (value) {
				*value++ = '\0';
				chromaprint_set_option(chromaprint_ctx, name, atoi(value));
			} else if (i + 1 < argc) {
        value = argv[++i];
        chromaprint_set_option(chromaprint_ctx, name, atoi(value));
      }
		}
	}

	for (i = 0; i < num_file_names; i++) {
		file_name = file_names[i];
		if (!decode_audio_file(chromaprint_ctx, buffer1, buffer2, file_name, max_length, &duration)) {
			fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
			continue;
		}
		if (i > 0) {
			printf("\n");
		}
		printf("FILE=%s\n", file_name);
		printf("DURATION=%d\n", duration);
		if (raw) {
			if (!chromaprint_get_raw_fingerprint(chromaprint_ctx, (void **)&raw_fingerprint, &raw_fingerprint_size)) {
				fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
				continue;
			}
			printf("FINGERPRINT=");
			for (j = 0; j < raw_fingerprint_size; j++) {
				printf("%d%s", raw_fingerprint[j], j + 1 < raw_fingerprint_size ? "," : "");
			}
			printf("\n");
			chromaprint_dealloc(raw_fingerprint);
		}
		else {
			if (!chromaprint_get_fingerprint(chromaprint_ctx, &fingerprint)) {
				fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
				continue;
			}
			printf("FINGERPRINT=%s\n", fingerprint);
			chromaprint_dealloc(fingerprint);
		}
	}

	chromaprint_free(chromaprint_ctx);
	av_free(buffer1);
	av_free(buffer2);
	free(file_names);

	return 0;
}
Exemplo n.º 16
0
	AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg)
		: ppu_thread("HLE Audio Decoder")
		, type(type)
		, memAddr(addr)
		, memSize(size)
		, memBias(0)
		, cbFunc(func)
		, cbArg(arg)
		, is_closed(false)
		, is_finished(false)
		, just_started(false)
		, just_finished(false)
		, codec(nullptr)
		, input_format(nullptr)
		, ctx(nullptr)
		, fmt(nullptr)
	{
		av_register_all();
		avcodec_register_all();

		switch (type)
		{
		case CELL_ADEC_TYPE_ATRACX:
		case CELL_ADEC_TYPE_ATRACX_2CH:
		case CELL_ADEC_TYPE_ATRACX_6CH:
		case CELL_ADEC_TYPE_ATRACX_8CH:
		{
			codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P);
			input_format = av_find_input_format("oma");
			break;
		}
		case CELL_ADEC_TYPE_MP3:
		{
			codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
			input_format = av_find_input_format("mp3");
			break;
		}
		default:
		{
			fmt::throw_exception("Unknown type (0x%x)" HERE, type);
		}
		}

		if (!codec)
		{
			fmt::throw_exception("avcodec_find_decoder() failed" HERE);
		}
		if (!input_format)
		{
			fmt::throw_exception("av_find_input_format() failed" HERE);
		}
		fmt = avformat_alloc_context();
		if (!fmt)
		{
			fmt::throw_exception("avformat_alloc_context() failed" HERE);
		}
		io_buf = (u8*)av_malloc(4096);
		fmt->pb = avio_alloc_context(io_buf, 256, 0, this, adecRead, NULL, NULL);
		if (!fmt->pb)
		{
			fmt::throw_exception("avio_alloc_context() failed" HERE);
		}
	}
Exemplo n.º 17
0
bool CFfmpegDec::SetMetaData(FILE *_in, CAudioMetaData* m, bool save_cover)
{
	if (!meta_data_valid)
	{
		if (!Init(_in, (const CFile::FileType) m->type))
			return false;

		mutex.lock();
		int ret = avformat_find_stream_info(avc, NULL);
		if (ret < 0) {
			mutex.unlock();
			DeInit();
			printf("avformat_find_stream_info error %d\n", ret);
			return false;
		}
		mutex.unlock();
		if (!is_stream) {
			GetMeta(avc->metadata);
			for(unsigned int i = 0; i < avc->nb_streams; i++) {
				if (avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
					GetMeta(avc->streams[i]->metadata);
			}
		}

		//fseek((FILE *) in, 0, SEEK_SET);
#ifdef FFDEC_DEBUG
		av_dump_format(avc, 0, "", 0);
#endif

		codec = NULL;
		best_stream = av_find_best_stream(avc, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);

		if (best_stream < 0) {
			DeInit();
			return false;
		}

		if (!codec)
			codec = avcodec_find_decoder(avc->streams[best_stream]->codec->codec_id);
		samplerate = avc->streams[best_stream]->codec->sample_rate;
		mChannels = av_get_channel_layout_nb_channels(avc->streams[best_stream]->codec->channel_layout);

		std::stringstream ss;

		if (codec && codec->long_name != NULL)
			type_info = codec->long_name;
		else if(codec && codec->name != NULL)
			type_info = codec->name;
		else
			type_info = "unknown";
		ss << " / " << mChannels << " channel" << ( mChannels > 1 ? "s" : "");
		type_info += ss.str();

		bitrate = 0;
		total_time = 0;

		if (avc->duration != int64_t(AV_NOPTS_VALUE))
			total_time = avc->duration / int64_t(AV_TIME_BASE);
		printf("CFfmpegDec: format %s (%s) duration %ld\n", avc->iformat->name, type_info.c_str(), total_time);

		for(unsigned int i = 0; i < avc->nb_streams; i++) {
			if (avc->streams[i]->codec->bit_rate > 0)
				bitrate += avc->streams[i]->codec->bit_rate;
			if (save_cover && (avc->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
				mkdir(COVERDIR, 0755);
				std::string cover(COVERDIR);
				cover += "/" + to_string(cover_count++) + ".jpg";
				FILE *f = fopen(cover.c_str(), "wb");
				if (f) {
					AVPacket *pkt = &avc->streams[i]->attached_pic;
					fwrite(pkt->data, pkt->size, 1, f);
					fclose(f);
					m->cover = cover;
					m->cover_temporary = true;
				}
			}
		}
		if(!total_time && m->filesize && bitrate)
			total_time = 8 * m->filesize / bitrate;

		meta_data_valid = true;
		m->changed = true;
	}
	if (!is_stream) {
		m->title = title;
		m->artist = artist;
		m->date = date;
		m->album = album;
		m->genre = genre;
		m->total_time = total_time;
	}
	m->type_info = type_info;
	// make sure bitrate is set to prevent refresh metadata from gui, its a flag
	m->bitrate = bitrate ? bitrate : 1; 
	m->samplerate = samplerate;

	return true;
}
Exemplo n.º 18
0
/**
 * Cycle through available formats using the specified pin,
 * try to set parameters specified through AVOptions and if successful
 * return 1 in *pformat_set.
 * If pformat_set is NULL, list all pin capabilities.
 */
static void
dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
                    IPin *pin, int *pformat_set)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IAMStreamConfig *config = NULL;
    AM_MEDIA_TYPE *type = NULL;
    int format_set = 0;
    void *caps = NULL;
    int i, n, size;

    if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
        return;
    if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
        goto end;

    caps = av_malloc(size);
    if (!caps)
        goto end;

    for (i = 0; i < n && !format_set; i++) {
        IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);

#if DSHOWDEBUG
        ff_print_AM_MEDIA_TYPE(type);
#endif

        if (devtype == VideoDevice) {
            VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
            BITMAPINFOHEADER *bih;
            int64_t *fr;
#if DSHOWDEBUG
            ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
#endif
            if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
                VIDEOINFOHEADER *v = (void *) type->pbFormat;
                fr = &v->AvgTimePerFrame;
                bih = &v->bmiHeader;
            } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
                VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
                fr = &v->AvgTimePerFrame;
                bih = &v->bmiHeader;
            } else {
                goto next;
            }
            if (!pformat_set) {
                enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
                if (pix_fmt == AV_PIX_FMT_NONE) {
                    enum AVCodecID codec_id = dshow_codecid(bih->biCompression);
                    AVCodec *codec = avcodec_find_decoder(codec_id);
                    if (codec_id == AV_CODEC_ID_NONE || !codec) {
                        av_log(avctx, AV_LOG_INFO, "  unknown compression type 0x%X", (int) bih->biCompression);
                    } else {
                        av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
                    }
                } else {
                    av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
                }
                av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
                       vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
                       1e7 / vcaps->MaxFrameInterval,
                       vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
                       1e7 / vcaps->MinFrameInterval);
                continue;
            }
            if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
                if (ctx->video_codec_id != dshow_codecid(bih->biCompression))
                    goto next;
            }
            if (ctx->pixel_format != AV_PIX_FMT_NONE &&
                ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
                goto next;
            }
            if (ctx->framerate) {
                int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
                                            /  ctx->requested_framerate.num;
                if (framerate > vcaps->MaxFrameInterval ||
                    framerate < vcaps->MinFrameInterval)
                    goto next;
                *fr = framerate;
            }
            if (ctx->requested_width && ctx->requested_height) {
                if (ctx->requested_width  > vcaps->MaxOutputSize.cx ||
                    ctx->requested_width  < vcaps->MinOutputSize.cx ||
                    ctx->requested_height > vcaps->MaxOutputSize.cy ||
                    ctx->requested_height < vcaps->MinOutputSize.cy)
                    goto next;
                bih->biWidth  = ctx->requested_width;
                bih->biHeight = ctx->requested_height;
            }
        } else {
            AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
            WAVEFORMATEX *fx;
#if DSHOWDEBUG
            ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
#endif
            if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
                fx = (void *) type->pbFormat;
            } else {
                goto next;
            }
            if (!pformat_set) {
                av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
                       acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
                       acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
                continue;
            }
            if (ctx->sample_rate) {
                if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
                    ctx->sample_rate < acaps->MinimumSampleFrequency)
                    goto next;
                fx->nSamplesPerSec = ctx->sample_rate;
            }
            if (ctx->sample_size) {
                if (ctx->sample_size > acaps->MaximumBitsPerSample ||
                    ctx->sample_size < acaps->MinimumBitsPerSample)
                    goto next;
                fx->wBitsPerSample = ctx->sample_size;
            }
            if (ctx->channels) {
                if (ctx->channels > acaps->MaximumChannels ||
                    ctx->channels < acaps->MinimumChannels)
                    goto next;
                fx->nChannels = ctx->channels;
            }
        }
        if (IAMStreamConfig_SetFormat(config, type) != S_OK)
            goto next;
        format_set = 1;
next:
        if (type->pbFormat)
            CoTaskMemFree(type->pbFormat);
        CoTaskMemFree(type);
    }
end:
    IAMStreamConfig_Release(config);
    if (caps)
        av_free(caps);
    if (pformat_set)
        *pformat_set = format_set;
}
Exemplo n.º 19
0
u32 adecOpen(AudioDecoder* data)
{
	AudioDecoder& adec = *data;

	adec.adecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);

	u32 adec_id = cellAdec.GetNewId(data);

	adec.id = adec_id;

	adec.adecCb->SetName("Audio Decoder[" + std::to_string(adec_id) + "] Callback");

	thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [&]()
	{
		ConLog.Write("Audio Decoder enter()");

		AdecTask& task = adec.task;

		while (true)
		{
			if (Emu.IsStopped())
			{
				break;
			}

			if (adec.job.IsEmpty() && adec.is_running)
			{
				Sleep(1);
				continue;
			}

			/*if (adec.frames.GetCount() >= 50)
			{
				Sleep(1);
				continue;
			}*/

			if (!adec.job.Pop(task))
			{
				break;
			}

			switch (task.type)
			{
			case adecStartSeq:
				{
					// TODO: reset data
					ConLog.Warning("adecStartSeq:");

					adec.reader.addr = 0;
					adec.reader.size = 0;
					adec.reader.init = false;
					if (adec.reader.rem) free(adec.reader.rem);
					adec.reader.rem = nullptr;
					adec.reader.rem_size = 0;
					adec.is_running = true;
					adec.just_started = true;
				}
				break;

			case adecEndSeq:
				{
					// TODO: finalize
					ConLog.Warning("adecEndSeq:");

					/*Callback cb;
					cb.SetAddr(adec.cbFunc);
					cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
					cb.Branch(true); // ???*/
					adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);

					avcodec_close(adec.ctx);
					avformat_close_input(&adec.fmt);

					adec.is_running = false;
				}
				break;

			case adecDecodeAu:
				{
					int err = 0;

					adec.reader.addr = task.au.addr;
					adec.reader.size = task.au.size;
					//ConLog.Write("Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts);

					if (adec.just_started)
					{
						adec.first_pts = task.au.pts;
						adec.last_pts = task.au.pts - 0x10000; // hack
					}

					struct AVPacketHolder : AVPacket
					{
						AVPacketHolder(u32 size)
						{
							av_init_packet(this);

							if (size)
							{
								data = (u8*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
								memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
								this->size = size + FF_INPUT_BUFFER_PADDING_SIZE;
							}
							else
							{
								data = NULL;
								size = 0;
							}
						}

						~AVPacketHolder()
						{
							av_free(data);
							//av_free_packet(this);
						}

					} au(0);

					/*{
						wxFile dump;
						dump.Open(wxString::Format("audio pts-0x%llx.dump", task.au.pts), wxFile::write);
						u8* buf = (u8*)malloc(task.au.size);
						if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size);
						free(buf);
						dump.Close();
					}*/

					if (adec.just_started) // deferred initialization
					{
						err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL);
						if (err)
						{
							ConLog.Error("adecDecodeAu: avformat_open_input() failed");
							Emu.Pause();
							break;
						}
						AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ???
						if (!codec)
						{
							ConLog.Error("adecDecodeAu: avcodec_find_decoder() failed");
							Emu.Pause();
							break;
						}
						/*err = avformat_find_stream_info(adec.fmt, NULL);
						if (err)
						{
							ConLog.Error("adecDecodeAu: avformat_find_stream_info() failed");
							Emu.Pause();
							break;
						}
						if (!adec.fmt->nb_streams)
						{
							ConLog.Error("adecDecodeAu: no stream found");
							Emu.Pause();
							break;
						}*/
						if (!avformat_new_stream(adec.fmt, codec))
						{
							ConLog.Error("adecDecodeAu: avformat_new_stream() failed");
							Emu.Pause();
							break;
						}
						adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data

						AVDictionary* opts = nullptr;
						av_dict_set(&opts, "refcounted_frames", "1", 0);
						{
							SMutexGeneralLocker lock(g_mutex_avcodec_open2);
							// not multithread-safe
							err = avcodec_open2(adec.ctx, codec, &opts);
						}
						if (err)
						{
							ConLog.Error("adecDecodeAu: avcodec_open2() failed");
							Emu.Pause();
							break;
						}
						adec.just_started = false;
					}

					bool last_frame = false;

					while (true)
					{
						if (Emu.IsStopped())
						{
							ConLog.Warning("adecDecodeAu aborted");
							return;
						}

						/*if (!adec.ctx) // fake
						{
							AdecFrame frame;
							frame.pts = task.au.pts;
							frame.auAddr = task.au.addr;
							frame.auSize = task.au.size;
							frame.userdata = task.au.userdata;
							frame.size = 4096;
							frame.data = nullptr;
							adec.frames.Push(frame);

							adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);

							break;
						}*/

						last_frame = av_read_frame(adec.fmt, &au) < 0;
						if (last_frame)
						{
							//break;
							av_free(au.data);
							au.data = NULL;
							au.size = 0;
						}

						struct AdecFrameHolder : AdecFrame
						{
							AdecFrameHolder()
							{
								data = av_frame_alloc();
							}

							~AdecFrameHolder()
							{
								if (data)
								{
									av_frame_unref(data);
									av_frame_free(&data);
								}
							}

						} frame;

						if (!frame.data)
						{
							ConLog.Error("adecDecodeAu: av_frame_alloc() failed");
							Emu.Pause();
							break;
						}

						int got_frame = 0;

						int decode = avcodec_decode_audio4(adec.ctx, frame.data, &got_frame, &au);

						if (decode <= 0)
						{
							if (!last_frame && decode < 0)
							{
								ConLog.Error("adecDecodeAu: AU decoding error(0x%x)", decode);
							}
							if (!got_frame && adec.reader.size == 0) break;
						}

						if (got_frame)
						{
							u64 ts = av_frame_get_best_effort_timestamp(frame.data);
							if (ts != AV_NOPTS_VALUE)
							{
								frame.pts = ts/* - adec.first_pts*/;
								adec.last_pts = frame.pts;
							}
							else
							{
								adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000;
								frame.pts = adec.last_pts;
							}
							//frame.pts = adec.last_pts;
							//adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; // ???
							frame.auAddr = task.au.addr;
							frame.auSize = task.au.size;
							frame.userdata = task.au.userdata;
							frame.size = frame.data->nb_samples * frame.data->channels * sizeof(float);

							if (frame.data->format != AV_SAMPLE_FMT_FLTP)
							{
								ConLog.Error("adecDecodeaAu: unsupported frame format(%d)", frame.data->format);
								Emu.Pause();
								break;
							}
							if (frame.data->channels != 2)
							{
								ConLog.Error("adecDecodeAu: unsupported channel count (%d)", frame.data->channels);
								Emu.Pause();
								break;
							}

							//ConLog.Write("got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)",
								//frame.pts, frame.data->nb_samples, frame.data->channels, frame.data->sample_rate,
								//av_get_bytes_per_sample((AVSampleFormat)frame.data->format));

							adec.frames.Push(frame);
							frame.data = nullptr; // to prevent destruction

							/*Callback cb;
							cb.SetAddr(adec.cbFunc);
							cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
							cb.Branch(false);*/
							adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
						}
					}
						
					/*Callback cb;
					cb.SetAddr(adec.cbFunc);
					cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
					cb.Branch(false);*/
					adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
				}
				break;

			case adecClose:
				{
					adec.is_finished = true;
					ConLog.Write("Audio Decoder exit");
					return;
				}

			default:
				ConLog.Error("Audio Decoder error: unknown task(%d)", task.type);
			}
		}
		adec.is_finished = true;
		ConLog.Warning("Audio Decoder aborted");
	});

	t.detach();

	return adec_id;
}
Exemplo n.º 20
0
bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt)
{
  bool change = false;

  CDemuxStream* st = GetStream(pkt->iStreamId);
  if (st == nullptr)
    return change;

  if (st->ExtraSize)
    return change;

  CDemuxStreamClientInternal* stream = dynamic_cast<CDemuxStreamClientInternal*>(st);

  if (stream == nullptr ||
     stream->m_parser == nullptr)
    return change;

  if (stream->m_context == nullptr)
  {
    AVCodec *codec = avcodec_find_decoder(st->codec);
    if (codec == nullptr)
    {
      CLog::Log(LOGERROR, "%s - can't find decoder", __FUNCTION__);
      stream->DisposeParser();
      return change;
    }

    stream->m_context = avcodec_alloc_context3(codec);
    if (stream->m_context == nullptr)
    {
      CLog::Log(LOGERROR, "%s - can't allocate context", __FUNCTION__);
      stream->DisposeParser();
      return change;
    }
    stream->m_context->time_base.num = 1;
    stream->m_context->time_base.den = DVD_TIME_BASE;
  }

  if (stream->m_parser_split && stream->m_parser->parser->split)
  {
    int len = stream->m_parser->parser->split(stream->m_context, pkt->pData, pkt->iSize);
    if (len > 0 && len < FF_MAX_EXTRADATA_SIZE)
    {
      if (st->ExtraData)
        delete[] (uint8_t*)st->ExtraData;
      st->changes++;
      st->disabled = false;
      st->ExtraSize = len;
      st->ExtraData = new uint8_t[len+AV_INPUT_BUFFER_PADDING_SIZE];
      memcpy(st->ExtraData, pkt->pData, len);
      memset((uint8_t*)st->ExtraData + len, 0 , AV_INPUT_BUFFER_PADDING_SIZE);
      stream->m_parser_split = false;
      change = true;
      CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - split extradata");
    }
  }


  uint8_t *outbuf = nullptr;
  int outbuf_size = 0;
  int len = av_parser_parse2(stream->m_parser,
                             stream->m_context, &outbuf, &outbuf_size,
                             pkt->pData, pkt->iSize,
                             (int64_t)(pkt->pts * DVD_TIME_BASE),
                             (int64_t)(pkt->dts * DVD_TIME_BASE),
                             0);
  // our parse is setup to parse complete frames, so we don't care about outbufs
  if (len >= 0)
  {
    if (stream->m_context->profile != st->profile &&
        stream->m_context->profile != FF_PROFILE_UNKNOWN)
    {
      CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - {%d} profile changed from %d to %d", st->uniqueId, st->profile, stream->m_context->profile);
      st->profile = stream->m_context->profile;
      st->changes++;
      st->disabled = false;
    }

    if (stream->m_context->level != st->level &&
        stream->m_context->level != FF_LEVEL_UNKNOWN)
    {
      CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - {%d} level changed from %d to %d", st->uniqueId, st->level, stream->m_context->level);
      st->level = stream->m_context->level;
      st->changes++;
      st->disabled = false;
    }

    switch (st->type)
    {
      case STREAM_AUDIO:
      {
        CDemuxStreamClientInternalTpl<CDemuxStreamAudio>* sta = static_cast<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>*>(st);
        if (stream->m_context->channels != sta->iChannels &&
            stream->m_context->channels != 0)
        {
          CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - {%d} channels changed from %d to %d", st->uniqueId, sta->iChannels, stream->m_context->channels);
          sta->iChannels = stream->m_context->channels;
          sta->changes++;
          sta->disabled = false;
        }
        if (stream->m_context->sample_rate != sta->iSampleRate &&
            stream->m_context->sample_rate != 0)
        {
          CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - {%d} samplerate changed from %d to %d", st->uniqueId, sta->iSampleRate, stream->m_context->sample_rate);
          sta->iSampleRate = stream->m_context->sample_rate;
          sta->changes++;
          sta->disabled = false;
        }
        break;
      }
      case STREAM_VIDEO:
      {
        CDemuxStreamClientInternalTpl<CDemuxStreamVideo>* stv = static_cast<CDemuxStreamClientInternalTpl<CDemuxStreamVideo>*>(st);
        if (stream->m_context->width != stv->iWidth &&
            stream->m_context->width != 0)
        {
          CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - {%d} width changed from %d to %d", st->uniqueId, stv->iWidth, stream->m_context->width);
          stv->iWidth = stream->m_context->width;
          stv->changes++;
          stv->disabled = false;
        }
        if (stream->m_context->height != stv->iHeight &&
            stream->m_context->height != 0)
        {
          CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - {%d} height changed from %d to %d", st->uniqueId, stv->iHeight, stream->m_context->height);
          stv->iHeight = stream->m_context->height;
          stv->changes++;
          stv->disabled = false;
        }
        break;
      }

      default:
        break;
    }
  }
  else
    CLog::Log(LOGDEBUG, "%s - parser returned error %d", __FUNCTION__, len);

  return change;
}
Exemplo n.º 21
0
static void video_decode_example(const char *outfilename, const char *filename)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    int frame, got_picture, len;
    FILE *f;
    AVFrame *picture;
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
    char buf[1024];
    AVPacket avpkt;

    av_init_packet(&avpkt);

    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

    printf("Video decoding\n");

    /* find the mpeg1 video decoder */
    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);
    picture= avcodec_alloc_frame();

    if(codec->capabilities&CODEC_CAP_TRUNCATED)
        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */

    /* For some codecs, such as msmpeg4 and mpeg4, width and height
       MUST be initialized there because this information is not
       available in the bitstream. */

    /* open it */
    if (avcodec_open2(c, codec, NULL) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    /* the codec gives us the frame size, in samples */

    f = fopen(filename, "rb");
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }

    frame = 0;
    for(;;) {
        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
        if (avpkt.size == 0)
            break;

        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
           and this is the only method to use them because you cannot
           know the compressed data size before analysing it.

           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
           based, so you must call them with all the data for one
           frame exactly. You must also initialize 'width' and
           'height' before initializing them. */

        /* NOTE2: some codecs allow the raw parameters (frame size,
           sample rate) to be changed at any frame. We handle this, so
           you should also take care of it */

        /* here, we use a stream based decoder (mpeg1video), so we
           feed decoder and see if it could decode a frame */
        avpkt.data = inbuf;
        while (avpkt.size > 0) {
            len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
            if (len < 0) {
                fprintf(stderr, "Error while decoding frame %d\n", frame);
                exit(1);
            }
            if (got_picture) {
                printf("saving frame %3d\n", frame);
                fflush(stdout);

                /* the picture is allocated by the decoder. no need to
                   free it */
                snprintf(buf, sizeof(buf), outfilename, frame);
                pgm_save(picture->data[0], picture->linesize[0],
                         c->width, c->height, buf);
                frame++;
            }
            avpkt.size -= len;
            avpkt.data += len;
        }
    }

    /* some codecs, such as MPEG, transmit the I and P frame with a
       latency of one frame. You must do the following to have a
       chance to get the last frame of the video */
    avpkt.data = NULL;
    avpkt.size = 0;
    len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
    if (got_picture) {
        printf("saving last frame %3d\n", frame);
        fflush(stdout);

        /* the picture is allocated by the decoder. no need to
           free it */
        snprintf(buf, sizeof(buf), outfilename, frame);
        pgm_save(picture->data[0], picture->linesize[0],
                 c->width, c->height, buf);
        frame++;
    }

    fclose(f);

    avcodec_close(c);
    av_free(c);
    av_free(picture);
    printf("\n");
}
Exemplo n.º 22
0
int FFmpeg_Input::Open( const char *filepath ) {

  int error;

  /** Open the input file to read from it. */
  if ( (error = avformat_open_input( &input_format_context, filepath, NULL, NULL)) < 0 ) {

    Error("Could not open input file '%s' (error '%s')\n",
        filepath, av_make_error_string(error).c_str() );
    input_format_context = NULL;
    return error;
  } 

  /** Get information on the input file (number of streams etc.). */
  if ( (error = avformat_find_stream_info(input_format_context, NULL)) < 0 ) {
    Error( "Could not open find stream info (error '%s')\n",
        av_make_error_string(error).c_str() );
    avformat_close_input(&input_format_context);
    return error;
  }

  streams = new stream[input_format_context->nb_streams];

  for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
    if ( is_video_stream( input_format_context->streams[i] ) ) {
      zm_dump_stream_format(input_format_context, i, 0, 0);
      if ( video_stream_id == -1 ) {
        video_stream_id = i;
        // if we break, then we won't find the audio stream
      } else {
        Warning( "Have another video stream." );
      }
    } else if ( is_audio_stream( input_format_context->streams[i] ) ) {
      if ( audio_stream_id == -1 ) {
        audio_stream_id = i;
      } else {
        Warning( "Have another audio stream." );
      }
    }

    streams[i].frame_count = 0;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
    streams[i].context = avcodec_alloc_context3( NULL );
    avcodec_parameters_to_context( streams[i].context, input_format_context->streams[i]->codecpar );
#else
    streams[i].context = input_format_context->streams[i]->codec;
#endif

    if ( !(streams[i].codec = avcodec_find_decoder(streams[i].context->codec_id)) ) {
      Error( "Could not find input codec\n");
      avformat_close_input(&input_format_context);
      return AVERROR_EXIT;
    } else {
      Debug(1, "Using codec (%s) for stream %d", streams[i].codec->name, i );
    }

    if ((error = avcodec_open2( streams[i].context, streams[i].codec, NULL)) < 0) {
      Error( "Could not open input codec (error '%s')\n",
          av_make_error_string(error).c_str() );
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
      avcodec_free_context( &streams[i].context );
#endif
      avformat_close_input(&input_format_context);
      return error;
    }
  } // end foreach stream

  if ( video_stream_id == -1 )
    Error( "Unable to locate video stream in %s", filepath );
  if ( audio_stream_id == -1 )
    Debug( 3, "Unable to locate audio stream in %s", filepath );

  return 0;
} // end int FFmpeg_Input::Open( const char * filepath )
Exemplo n.º 23
0
static int isffmpeg (const char *filename) {
    AVFormatContext *pFormatCtx;
    unsigned int i;
    int videoStream;
    AVCodec *pCodec;
    AVCodecContext *pCodecCtx;

    do_init_ffmpeg();

    if( BLI_testextensie(filename, ".swf") ||
            BLI_testextensie(filename, ".jpg") ||
            BLI_testextensie(filename, ".png") ||
            BLI_testextensie(filename, ".dds") ||
            BLI_testextensie(filename, ".tga") ||
            BLI_testextensie(filename, ".bmp") ||
            BLI_testextensie(filename, ".exr") ||
            BLI_testextensie(filename, ".cin") ||
            BLI_testextensie(filename, ".wav")) return 0;

    if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {
        if(UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
        return 0;
    }

    if(av_find_stream_info(pFormatCtx)<0) {
        if(UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
        av_close_input_file(pFormatCtx);
        return 0;
    }

    if(UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);


    /* Find the first video stream */
    videoStream=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++)
        if(pFormatCtx->streams[i] &&
                pFormatCtx->streams[i]->codec &&
                (pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO))
        {
            videoStream=i;
            break;
        }

    if(videoStream==-1) {
        av_close_input_file(pFormatCtx);
        return 0;
    }

    pCodecCtx = pFormatCtx->streams[videoStream]->codec;

    /* Find the decoder for the video stream */
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL) {
        av_close_input_file(pFormatCtx);
        return 0;
    }

    if(avcodec_open(pCodecCtx, pCodec)<0) {
        av_close_input_file(pFormatCtx);
        return 0;
    }

    avcodec_close(pCodecCtx);
    av_close_input_file(pFormatCtx);

    return 1;
}
Exemplo n.º 24
0
static HRESULT FFMVWrapper_BeginTransform( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, BOOL bReuseSample )
{
	CFFMVWrapperImpl*	This = pImpl->m_pUserData;
	BITMAPINFO*	pbiIn = NULL;
	BITMAPINFO*	pbiOut = NULL;
	LONG	width, height;
	DWORD	dwFourCC;
	AVCodec*	codec;
	HRESULT hr;
	int	i;

	TRACE("(%p,%p,%p,%d)\n",This,pmtIn,pmtOut,bReuseSample);

	if ( This == NULL || This->ctx.codec )
		return E_UNEXPECTED;

	hr = FFMVWrapper_CheckMediaType( pImpl, pmtIn, pmtOut );
	if ( FAILED(hr) )
		return hr;

	FFMVWrapper_ReleaseDIBBuffers(This);

	if ( IsEqualGUID( &pmtIn->formattype, &FORMAT_VideoInfo ) )
	{
		pbiIn = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
		dwFourCC = pbiIn->bmiHeader.biCompression;
	}
	else if ( IsEqualGUID( &pmtIn->formattype, &FORMAT_MPEGVideo ) )
	{
		pbiIn = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
		dwFourCC = mmioFOURCC('P','I','M','1');
	}
	else return E_FAIL;

	width = pbiIn->bmiHeader.biWidth;
	height = (pbiIn->bmiHeader.biHeight < 0) ?
		 -pbiIn->bmiHeader.biHeight :
		  pbiIn->bmiHeader.biHeight;

	pbiOut = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);

	This->m_pbiIn = FFMVWrapper_DuplicateBitmapInfo(pbiIn);
	This->m_pbiOut = FFMVWrapper_DuplicateBitmapInfo(pbiOut);
	if ( This->m_pbiIn == NULL || This->m_pbiOut == NULL )
		return E_OUTOFMEMORY;
	if ( This->m_pbiOut->bmiHeader.biCompression == 0 || This->m_pbiOut->bmiHeader.biCompression == 3 )
		This->m_pbiOut->bmiHeader.biSizeImage = DIBSIZE(This->m_pbiOut->bmiHeader);

	for (i=0; ff_codecs[i].dwFourCC && ff_codecs[i].dwFourCC != dwFourCC; i++);
	if (!ff_codecs[i].dwFourCC)
	{
		TRACE("couldn't find codec format\n");
		return E_FAIL;
	}

	codec = avcodec_find_decoder(ff_codecs[i].codec);
	if (!codec)
	{
		TRACE("couldn't open codec\n");
		return E_FAIL;
	}

	if ( !bReuseSample )
	{
		This->m_pOutBuf = QUARTZ_AllocMem(This->m_pbiOut->bmiHeader.biSizeImage);
		if ( This->m_pOutBuf == NULL )
			return E_OUTOFMEMORY;
		ZeroMemory( This->m_pOutBuf, This->m_pbiOut->bmiHeader.biSizeImage );
	}

	This->rtCur = 0;
	This->rtInternal = 0;

	EnterCriticalSection( &This->m_cs );

	avcodec_get_context_defaults( &This->ctx );
	This->ctx.width = width;
	This->ctx.height = height;
	if (codec->id == CODEC_ID_MPEG1VIDEO || codec->id == CODEC_ID_H264)
		This->ctx.flags |= CODEC_FLAG_TRUNCATED;
	TRACE("opening codec for %dx%d video\n", This->ctx.width, This->ctx.height);

	if (avcodec_open( &This->ctx, codec) < 0) {
		TRACE("couldn't open codec\n");
		return E_FAIL;
	}

	LeaveCriticalSection( &This->m_cs );

	return NOERROR;
}
int main(int argc, char* argv[])
{
	AVFormatContext	*pFormatCtx;
	int				i, videoindex;
	AVCodecContext	*pCodecCtx;
	AVCodec			*pCodec;
	AVFrame	*pFrame,*pFrameYUV;
	uint8_t *out_buffer;
	AVPacket *packet;
	int y_size;
	int ret, got_picture;
	struct SwsContext *img_convert_ctx;

	char filepath[]="bigbuckbunny_480x272.h265";
	//SDL---------------------------
	int screen_w=0,screen_h=0;
	SDL_Window *screen; 
	SDL_Renderer* sdlRenderer;
	SDL_Texture* sdlTexture;
	SDL_Rect sdlRect;

	FILE *fp_yuv;

	av_register_all();
	avformat_network_init();
	pFormatCtx = avformat_alloc_context();

	if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
		printf("Couldn't open input stream.\n");
		return -1;
	}
	if(avformat_find_stream_info(pFormatCtx,NULL)<0){
		printf("Couldn't find stream information.\n");
		return -1;
	}
	videoindex=-1;
	for(i=0; i<pFormatCtx->nb_streams; i++) 
		if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
			videoindex=i;
			break;
		}
	if(videoindex==-1){
		printf("Didn't find a video stream.\n");
		return -1;
	}
	pCodecCtx=pFormatCtx->streams[videoindex]->codec;
	pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
	if(pCodec==NULL){
		printf("Codec not found.\n");
		return -1;
	}
	if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
		printf("Could not open codec.\n");
		return -1;
	}
	
	pFrame=av_frame_alloc();
	pFrameYUV=av_frame_alloc();
	out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
	avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
	packet=(AVPacket *)av_malloc(sizeof(AVPacket));
	//Output Info-----------------------------
	printf("--------------- File Information ----------------\n");
	av_dump_format(pFormatCtx,0,filepath,0);
	printf("-------------------------------------------------\n");
	img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 
		pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); 

#if OUTPUT_YUV420P 
    fp_yuv=fopen("output.yuv","wb+");  
#endif  
	
	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  
		printf( "Could not initialize SDL - %s\n", SDL_GetError()); 
		return -1;
	} 

	screen_w = pCodecCtx->width;
	screen_h = pCodecCtx->height;
	//SDL 2.0 Support for multiple windows
	screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		screen_w, screen_h,
		SDL_WINDOW_OPENGL);

	if(!screen) {  
		printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  
		return -1;
	}

	sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  
	//IYUV: Y + U + V  (3 planes)
	//YV12: Y + V + U  (3 planes)
	sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);  

	sdlRect.x=0;
	sdlRect.y=0;
	sdlRect.w=screen_w;
	sdlRect.h=screen_h;

	//SDL End----------------------
	while(av_read_frame(pFormatCtx, packet)>=0){
		if(packet->stream_index==videoindex){
			ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
			if(ret < 0){
				printf("Decode Error.\n");
				return -1;
			}
			if(got_picture){
				sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, 
					pFrameYUV->data, pFrameYUV->linesize);
				
#if OUTPUT_YUV420P
				y_size=pCodecCtx->width*pCodecCtx->height;  
				fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y 
				fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
				fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
#endif
				//SDL---------------------------
#if 0
				SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );  
#else
				SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
				pFrameYUV->data[0], pFrameYUV->linesize[0],
				pFrameYUV->data[1], pFrameYUV->linesize[1],
				pFrameYUV->data[2], pFrameYUV->linesize[2]);
#endif	
				
				SDL_RenderClear( sdlRenderer );  
				SDL_RenderCopy( sdlRenderer, sdlTexture,  NULL, &sdlRect);  
				SDL_RenderPresent( sdlRenderer );  
				//SDL End-----------------------
				//Delay 40ms
				SDL_Delay(40);
			}
		}
		av_free_packet(packet);
	}
	//flush decoder
	//FIX: Flush Frames remained in Codec
	while (1) {
		ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
		if (ret < 0)
			break;
		if (!got_picture)
			break;
		sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, 
			pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
		int y_size=pCodecCtx->width*pCodecCtx->height;  
		fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y 
		fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
		fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
#endif
		//SDL---------------------------
		SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );  
		SDL_RenderClear( sdlRenderer );  
		SDL_RenderCopy( sdlRenderer, sdlTexture,  NULL, &sdlRect);  
		SDL_RenderPresent( sdlRenderer );  
		//SDL End-----------------------
		//Delay 40ms
		SDL_Delay(40);
	}

	sws_freeContext(img_convert_ctx);

#if OUTPUT_YUV420P 
    fclose(fp_yuv);
#endif 

	SDL_Quit();

	av_frame_free(&pFrameYUV);
	av_frame_free(&pFrame);
	avcodec_close(pCodecCtx);
	avformat_close_input(&pFormatCtx);

	return 0;
}
Exemplo n.º 26
0
int setupDemuxerCodecs(DemuxerSettings *ds) {
	AVCodec *pCodecVideo, *pCodecAudio, *pCodecSub;

	if (ds->do_video) {
                ds->pCodecCtxVideo = ds->pFormatCtx->streams[ds->videoStream]->codec;

                // Find the decoder for the video stream
                pCodecVideo = avcodec_find_decoder(ds->pCodecCtxVideo->codec_id);
                if (pCodecVideo == NULL) {
                        av_log(NULL, AV_LOG_FATAL,
                                "Error: Codec [%d] for video not found.\n", ds->pCodecCtxVideo->codec_id);
                        return -1;        // Codec not found
                }
                // Open video codec
                if (avcodec_open(ds->pCodecCtxVideo, pCodecVideo) < 0) {
                        av_log(NULL, AV_LOG_FATAL,
                                "Error: Codec for video not able to open.\n");
                        return -1;        // Could not open codec
                }
                // Hack to correct wrong frame rates that seem to be generated by some codecs
                if (ds->pCodecCtxVideo->time_base.num > 1000
                    && ds->pCodecCtxVideo->time_base.den == 1)
                        ds->pCodecCtxVideo->time_base.den = 1000;
	}

	if (ds->do_audio) {
                ds->pCodecCtxAudio = ds->pFormatCtx->streams[ds->audioStream]->codec;

                // Find the decoder for the audio stream
                pCodecAudio = avcodec_find_decoder(ds->pCodecCtxAudio->codec_id);
                if (pCodecAudio == NULL) {
                        av_log(NULL, AV_LOG_FATAL,
                                "Error: Codec [%d] for audio not found.\n", ds->pCodecCtxAudio->codec_id);
                        return -1;        // Codec not found
                }
                // Open audio codec
                if (avcodec_open(ds->pCodecCtxAudio, pCodecAudio) < 0) {
                        av_log(NULL, AV_LOG_FATAL,
                                "Error: Codec for audio not able to open.\n");
                        return -1;        // Could not open codec
                }
	}

	if (ds->do_sub) {
                ds->pCodecCtxSub = ds->pFormatCtx->streams[ds->subStream]->codec;

                // Find the decoder for the subtitle stream
                pCodecSub = avcodec_find_decoder(ds->pCodecCtxSub->codec_id);
                if (pCodecSub == NULL) {
                        av_log(NULL, AV_LOG_FATAL,
                                "Error: Codec [%d] for subtitle not found.\n", ds->pCodecCtxSub->codec_id);
                        //return -1;        // Codec not found
			ds->pCodecCtxSub = NULL;
                }
                // Open subtitle codec
                if (ds->pCodecCtxSub && avcodec_open(ds->pCodecCtxSub, pCodecSub) < 0) {
                        av_log(NULL, AV_LOG_FATAL,
                                "Error: Codec for subtitle not able to open.\n");
                        return -1;        // Could not open codec
                }
	}

	return 0;	
}