コード例 #1
0
ファイル: format.c プロジェクト: ovtn/libav
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened,
                                      int *score_max)
{
    AVProbeData lpd = *pd;
    AVInputFormat *fmt1 = NULL, *fmt;
    int score, id3 = 0;

    if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
        int id3len = ff_id3v2_tag_len(lpd.buf);
        if (lpd.buf_size > id3len + 16) {
            lpd.buf      += id3len;
            lpd.buf_size -= id3len;
        }
        id3 = 1;
    }

    fmt = NULL;
    while ((fmt1 = av_iformat_next(fmt1))) {
        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
            continue;
        score = 0;
        if (fmt1->read_probe) {
            score = fmt1->read_probe(&lpd);
        } else if (fmt1->extensions) {
            if (av_match_ext(lpd.filename, fmt1->extensions))
                score = AVPROBE_SCORE_EXTENSION;
        }
        if (av_match_name(lpd.mime_type, fmt1->mime_type))
            score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
        if (score > *score_max) {
            *score_max = score;
            fmt        = fmt1;
        } else if (score == *score_max)
            fmt = NULL;
    }

    // A hack for files with huge id3v2 tags -- try to guess by file extension.
    if (!fmt && is_opened && *score_max < AVPROBE_SCORE_EXTENSION / 2) {
        while ((fmt = av_iformat_next(fmt)))
            if (fmt->extensions &&
                av_match_ext(lpd.filename, fmt->extensions)) {
                *score_max = AVPROBE_SCORE_EXTENSION / 2;
                break;
            }
    }

    if (!fmt && id3 && *score_max < AVPROBE_SCORE_EXTENSION / 2 - 1) {
        while ((fmt = av_iformat_next(fmt)))
            if (fmt->extensions && av_match_ext("mp3", fmt->extensions)) {
                *score_max = AVPROBE_SCORE_EXTENSION / 2 - 1;
                break;
            }
    }

    return fmt;
}
コード例 #2
0
ファイル: format.c プロジェクト: FSBenArchard/FFmpeg
AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened,
                                      int *score_ret)
{
    AVProbeData lpd = *pd;
    AVInputFormat *fmt1 = NULL, *fmt;
    int score, nodat = 0, score_max = 0;
    const static uint8_t zerobuffer[AVPROBE_PADDING_SIZE];

    if (!lpd.buf)
        lpd.buf = zerobuffer;

    if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
        int id3len = ff_id3v2_tag_len(lpd.buf);
        if (lpd.buf_size > id3len + 16) {
            lpd.buf      += id3len;
            lpd.buf_size -= id3len;
        } else if (id3len >= PROBE_BUF_MAX) {
            nodat = 2;
        } else
            nodat = 1;
    }

    fmt = NULL;
    while ((fmt1 = av_iformat_next(fmt1))) {
        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
            continue;
        score = 0;
        if (fmt1->read_probe) {
            score = fmt1->read_probe(&lpd);
            if (fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) {
                if      (nodat == 0) score = FFMAX(score, 1);
                else if (nodat == 1) score = FFMAX(score, AVPROBE_SCORE_EXTENSION / 2 - 1);
                else                 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
            }
        } else if (fmt1->extensions) {
            if (av_match_ext(lpd.filename, fmt1->extensions))
                score = AVPROBE_SCORE_EXTENSION;
        }
#if FF_API_PROBE_MIME
        if (av_match_name(lpd.mime_type, fmt1->mime_type))
            score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
#endif
        if (score > score_max) {
            score_max = score;
            fmt       = fmt1;
        } else if (score == score_max)
            fmt = NULL;
    }
    if (nodat == 1)
        score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
    *score_ret = score_max;

    return fmt;
}
コード例 #3
0
ファイル: img2dec.c プロジェクト: vaqeteart/FFmpeg
static int img_read_probe(AVProbeData *p)
{
    if (p->filename && ff_guess_image2_codec(p->filename)) {
        if (av_filename_number_test(p->filename))
            return AVPROBE_SCORE_MAX;
        else if (is_glob(p->filename))
            return AVPROBE_SCORE_MAX;
        else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif"))
            return 5;
        else
            return AVPROBE_SCORE_EXTENSION;
    }
    return 0;
}
コード例 #4
0
ファイル: format.c プロジェクト: bas-t/mythtv
AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
                                const char *mime_type)
{
    AVOutputFormat *fmt = NULL, *fmt_found;
    int score_max, score;

    /* specific test for image sequences */
#if CONFIG_IMAGE2_MUXER
    if (!short_name && filename &&
        av_filename_number_test(filename) &&
        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
        return av_guess_format("image2", NULL, NULL);
    }
#endif
    /* Find the proper file type. */
    fmt_found = NULL;
    score_max = 0;
    while ((fmt = av_oformat_next(fmt))) {
        score = 0;
        if (fmt->name && short_name && av_match_name(short_name, fmt->name))
            score += 100;
        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
            score += 10;
        if (filename && fmt->extensions &&
            av_match_ext(filename, fmt->extensions)) {
            score += 5;
        }
        if (score > score_max) {
            score_max = score;
            fmt_found = fmt;
        }
    }
    return fmt_found;
}
コード例 #5
0
ファイル: ffserver.c プロジェクト: mobdim/ffmpeg-streaming
static SFF* sff_read(HTTPContext *c, int type)
{
	HTTPContext *f = c->feed_ctx;
	SFF *sff = NULL;
	int idx = 1 == type ? N : c->sff_r;

	if(!f){
		return NULL;
	}
	
	sff = f->sff_pkts[idx];
	if(!(sff && sff->wflag == 2)){
		return NULL;
	}
	
	if(1 == type){
		return f->sff_pkts[N];
	}

	if(av_match_ext(c->url, "flv") && FFABS(c->sff_r - f->sff_w) <= 0){
		return NULL;
	}
	
	sff = f->sff_pkts[c->sff_r];
	c->sff_r = (c->sff_r + 1)%N;
	return sff;
}
コード例 #6
0
ファイル: img2dec.c プロジェクト: Innovattic/FFmpeg
static int img_read_probe(AVProbeData *p)
{
    if (p->filename && ff_guess_image2_codec(p->filename)) {
        if (av_filename_number_test(p->filename))
            return AVPROBE_SCORE_MAX;
        else if (is_glob(p->filename))
            return AVPROBE_SCORE_MAX;
        else if (p->filename[strcspn(p->filename, "*?{")]) // probably PT_GLOB
            return AVPROBE_SCORE_EXTENSION + 2; // score chosen to be a tad above the image pipes
        else if (p->buf_size == 0)
            return 0;
        else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif"))
            return 5;
        else
            return AVPROBE_SCORE_EXTENSION;
    }
    return 0;
}
コード例 #7
0
ファイル: libmodplug.c プロジェクト: Bjelijah/EcamTurnH265
static int modplug_probe(AVProbeData *p)
{
    if (av_match_ext(p->filename, modplug_extensions)) {
        if (p->buf_size < 16384)
            return AVPROBE_SCORE_EXTENSION/2-1;
        else
            return AVPROBE_SCORE_EXTENSION;
    }
    return 0;
}
コード例 #8
0
ファイル: ffserver.c プロジェクト: mobdim/ffmpeg-streaming
static int sff_close(void)
{
	HTTPContext *c = NULL, *c_next = NULL;
	
	for(c = first_http_ctx; c != NULL; c = c_next){
		c_next = c->next;
		if(c->post && av_match_ext(c->url, "flv")){
			printf("sff close %s\n", c->url);
			close_connection(c);
		}
	}
	return 0;
}
コード例 #9
0
ファイル: img2dec.c プロジェクト: Innovattic/FFmpeg
static int pgmyuv_probe(AVProbeData *p) // custom FFmpeg format recognized by file extension
{
    int ret = pgmx_probe(p);
    return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0;
}
コード例 #10
0
ファイル: img2dec.c プロジェクト: Innovattic/FFmpeg
static int pgm_probe(AVProbeData *p)
{
    int ret = pgmx_probe(p);
    return ret && !av_match_ext(p->filename, "pgmyuv") ? ret : 0;
}
コード例 #11
0
ファイル: format.c プロジェクト: bas-t/mythtv
AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened,
                                      int *score_ret)
{
    AVProbeData lpd = *pd;
    AVInputFormat *fmt1 = NULL, *fmt;
    int score, score_max = 0;
    const static uint8_t zerobuffer[AVPROBE_PADDING_SIZE];
    enum nodat {
        NO_ID3,
        ID3_ALMOST_GREATER_PROBE,
        ID3_GREATER_PROBE,
        ID3_GREATER_MAX_PROBE,
    } nodat = NO_ID3;

    if (!lpd.buf)
        lpd.buf = (unsigned char *) zerobuffer;

    if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
        int id3len = ff_id3v2_tag_len(lpd.buf);
        if (lpd.buf_size > id3len + 16) {
            if (lpd.buf_size < 2LL*id3len + 16)
                nodat = ID3_ALMOST_GREATER_PROBE;
            lpd.buf      += id3len;
            lpd.buf_size -= id3len;
        } else if (id3len >= PROBE_BUF_MAX) {
            nodat = ID3_GREATER_MAX_PROBE;
        } else
            nodat = ID3_GREATER_PROBE;
    }

    fmt = NULL;
    while ((fmt1 = av_iformat_next(fmt1))) {
        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE) && strcmp(fmt1->name, "image2"))
            continue;
        score = 0;
        if (fmt1->read_probe) {
            score = fmt1->read_probe(&lpd);
            if (score)
                av_log(NULL, AV_LOG_TRACE, "Probing %s score:%d size:%d\n", fmt1->name, score, lpd.buf_size);
            if (fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) {
                switch (nodat) {
                case NO_ID3:
                    score = FFMAX(score, 1);
                    break;
                case ID3_GREATER_PROBE:
                case ID3_ALMOST_GREATER_PROBE:
                    score = FFMAX(score, AVPROBE_SCORE_EXTENSION / 2 - 1);
                    break;
                case ID3_GREATER_MAX_PROBE:
                    score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
                    break;
                }
            }
        } else if (fmt1->extensions) {
            if (av_match_ext(lpd.filename, fmt1->extensions))
                score = AVPROBE_SCORE_EXTENSION;
        }
        if (av_match_name(lpd.mime_type, fmt1->mime_type)) {
            if (AVPROBE_SCORE_MIME > score) {
                av_log(NULL, AV_LOG_DEBUG, "Probing %s score:%d increased to %d due to MIME type\n", fmt1->name, score, AVPROBE_SCORE_MIME);
                score = AVPROBE_SCORE_MIME;
            }
        }
        if (score > score_max) {
            score_max = score;
            fmt       = fmt1;
        } else if (score == score_max) {
            // if the conflict is between Myth MPEGTS demux and FFMPEG's origin
            // use mythtv's one
            if ((fmt1 == &ff_mpegts_demuxer && fmt == &ff_mythtv_mpegts_demuxer) ||
                (fmt == &ff_mpegts_demuxer && fmt1 == &ff_mythtv_mpegts_demuxer)) {
                fmt = &ff_mythtv_mpegts_demuxer;
            } else if ((fmt1 == &ff_mpegts_demuxer && fmt == &ff_mythtv_mpegtsraw_demuxer) ||
                      (fmt == &ff_mpegts_demuxer && fmt1 == &ff_mythtv_mpegtsraw_demuxer)) {
                fmt = &ff_mythtv_mpegtsraw_demuxer;
            } else {
                fmt = NULL;
            }
        }
    }
    if (nodat == ID3_GREATER_PROBE)
        score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
    *score_ret = score_max;

    return fmt;
}
コード例 #12
0
ファイル: result.c プロジェクト: dsully/libmediascan
// Scan a video file with libavformat
static int
scan_video(MediaScanResult *r)
{
  AVFormatContext *avf = NULL;
  AVInputFormat *iformat = NULL;
  int AVError = 0;
  int ret = 1;

  if (r->flags & USE_EXTENSION) {
    // Set AVInputFormat based on file extension to avoid guessing
    while ((iformat = av_iformat_next(iformat))) {
      if ( av_match_ext(r->path, iformat->name) )
        break;

      if (iformat->extensions) {
        if ( av_match_ext(r->path, iformat->extensions) )
          break;
      }
    }

    if (iformat)
      LOG_INFO("Forcing format: %s\n", iformat->name);
  }

  if ( (AVError = av_open_input_file(&avf, r->path, iformat, 0, NULL)) != 0 ) {
    r->error = error_create(r->path, MS_ERROR_FILE, "[libavformat] Unable to open file for reading");
    r->error->averror = AVError;
    ret = 0;
    goto out;
  }

  if ( (AVError = av_find_stream_info(avf)) < 0 ) {
    r->error = error_create(r->path, MS_ERROR_READ, "[libavformat] Unable to find stream info");
    r->error->averror = AVError;
    ret = 0;
    goto out;
  }

#ifdef DEBUG
  dump_format(avf, 0, r->path, 0);
#endif

  r->_avf = (void *)avf;
  
  // General metadata
  // XXX r->mime_type = get_mime_type(r);
  // XXX r->dlna_profile = get_dlna_profile(r);
  // XXX r->size
  // XXX r->mtime
  r->bitrate     = avf->bit_rate / 1000;
  r->duration_ms = avf->duration / 1000;

  // Video-specific metadata
  r->type_data.video = video_create();

/*
  s->type_name   = avf->iformat->long_name;
  s->metadata    = avf->metadata;
  s->nstreams    = avf->nb_streams;

  if (avf->nb_streams) {
    mediascan_add_StreamData(s, avf->nb_streams);

    int i;
    for (i = 0; i < s->nstreams; i++) {    
      AVStream *st = avf->streams[i];

      switch (st->codec->codec_type) {
        case AVMEDIA_TYPE_VIDEO:
          s->streams[i].type = TYPE_VIDEO;
          s->streams[i].bitrate = st->codec->bit_rate;
          s->streams[i].width = st->codec->width;
          s->streams[i].height = st->codec->height;

          if (st->avg_frame_rate.num && st->avg_frame_rate.den)
            s->streams[i].fps = st->avg_frame_rate.num / (double)st->avg_frame_rate.den;
          break;
        case AVMEDIA_TYPE_AUDIO:
        {
          int bps = av_get_bits_per_sample(st->codec->codec_id); // bps for PCM types

          s->streams[i].type = TYPE_AUDIO;
          s->streams[i].samplerate = st->codec->sample_rate;
          s->streams[i].channels = st->codec->channels;
          s->streams[i].bit_depth = 0; // XXX not supported by libavformat
          s->streams[i].bitrate = bps
            ? st->codec->sample_rate * st->codec->channels * bps
            : st->codec->bit_rate;
          break;
        }
        default:
          s->streams[i].type = TYPE_UNKNOWN;
          break;
      }

      if (s->streams[i].bitrate)
        s->streams[i].bitrate /= 1000;

      AVCodec *c = avcodec_find_decoder(st->codec->codec_id);  
      if (c) {
        s->streams[i].codec_name = c->name;
      }
      else if (st->codec->codec_name[0] != '\0') {
        s->streams[i].codec_name = st->codec->codec_name;
      }
      else {
        s->streams[i].codec_name = "Unknown";
      }
    }
  }
*/

out:
  return ret;
}
コード例 #13
0
ファイル: ffserver.c プロジェクト: mobdim/ffmpeg-streaming
/* parse HTTP request and prepare header */
static int http_parse_request(HTTPContext *c)
{
    char *q, msg[1024];
    const char *mime_type, *p;
	HTTPContext *ctx;
	int ret = 0, is_first = 0;
	const char *first_tag = "First-Request=0";
	RequestData rd = {{0}};

    p = c->buffer;
	while(get_line(msg, sizeof(msg), &p) > 0){
		ret = handle_line(c, msg, sizeof(msg), &rd);
		if(ret < 0)return ret;
	}
	is_first = !av_stristr(rd.cookie, first_tag);
	
	if(c->post && c->content_length 
		&& !av_match_ext(c->url, "m3u8")
		&& !av_match_ext(c->url, "ts")
		&& !av_match_ext(c->url, "flv")){
		c->post = 0;
		c->content_length = read_request_content(c, rd.content, sizeof(rd.content));
	}
	#if defined(PLUGIN_DVB)
	if(!c->post && !strcmp(c->url, "digitalDvb/allServiceType/getClientInfo")){
		uint32_t *ptr = (uint32_t*)rd.content, *ptr_end = (uint32_t*)(rd.content+sizeof(rd.content)-8);
		for(ctx = first_http_ctx; ctx; ctx = ctx->next) 
			if(!ctx->post && av_match_ext(ctx->url, "flv") )
			{/*todo: record hls*/
				if(ptr < ptr_end){
					int chid = -1;
					sscanf(ctx->url, "%d", &chid);
		
					*ptr++ = inet_addr(inet_ntoa(ctx->from_addr.sin_addr));
					*ptr++ = chid;

					printf("ip %s id %u %s\t", inet_ntoa(ctx->from_addr.sin_addr), chid, ctx->url);
				}
			}
	}
	#endif

    //http_log("New conn: %s:%u %d %s cookie:%s\n", inet_ntoa(c->from_addr.sin_addr), ntohs(c->from_addr.sin_port), c->post, c->url, rd.cookie);

	/*handle m3u8/ts request solely*/
	if(av_match_ext(c->url, "m3u8") 
			|| av_match_ext(c->url, "ts")){
		c->keep_alive = 0; 
		ret = hls_parse_request(c, c->url, is_first);
		if(ret < 0)goto send_error;
		else if(ret == 1){
			long chid = atoi(c->url);
			if(!(0 <= chid && chid <= 10000)){
				sprintf(msg, "bad request: %s-->%ld", c->url, chid);
				http_log("%s\n", msg);
				goto send_error;
			}
			#if defined(PLUGIN_DVB)
			ff_ctl_send_string(1, c->url, rd.content);
			#endif
			http_log("wait get %s\n", c->url);
		}
		if(c->state == HTTPSTATE_SEND_HEADER)
			goto send_header;
		return 0; /*end here*/
	}

	#if defined(PLUGIN_DVB)
	ret = plugin_dvb(c, &rd);
	if(ret < 0){
		goto send_error;
	}else if(ret > 0){
		return 0;
	}
	#endif

    /*handle feed request*/
    if (c->post) {
		ctx = find_feed(c->url);
		if(ctx && ctx != c){
			sprintf(msg, "file %s has been feeded", c->url);
			http_log("%s\n", msg);
			goto send_error;
		}
        c->http_error = 0;
        c->state = HTTPSTATE_RECEIVE_DATA;
        return 0; /*end here*/
	}else{
		if(prepare_local_file(c) > 0){
			c->http_error = 200;
			c->state = HTTPSTATE_SEND_HEADER;
			return 0; /*no need feed, send local files directly.*/
		}
		
		ctx = find_feed(c->url);
		if(!ctx){
			c->keep_alive = 0; 
			sprintf(msg, "wait to get %s", c->url);
			http_log("%s\n", msg);
			#if defined(PLUGIN_DVB)
			ff_ctl_send(2, c->url, strlen(c->url)+1, rd.content, sizeof(rd.content)); 
			#endif
		}else{
			ctx->sff_ref_cnt++;
		}
		c->feed_ctx = ctx; 
	}

send_header:
    /* prepare HTTP header */
    c->buffer[0] = 0;
    av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.1 200 OK\r\n");
	mime_type =  get_mine_type(c->url);
    av_strlcatf(c->buffer, c->buffer_size, "Pragma: no-cache\r\n");
    av_strlcatf(c->buffer, c->buffer_size, "Content-Type: %s\r\n", mime_type);
	av_strlcatf(c->buffer, c->buffer_size, "Connection: %s\r\n", (c->keep_alive ? "keep-alive" : "close"));
	av_strlcatf(c->buffer, c->buffer_size, "Set-Cookie: %s; Path=/; Domain=%s\r\n", first_tag, rd.domain);
    av_strlcatf(c->buffer, c->buffer_size, "\r\n");

    q = c->buffer + strlen(c->buffer);

    /* prepare output buffer */
    c->http_error = 0;
    c->buffer_ptr = c->buffer;
    c->buffer_end = q;
    c->state = HTTPSTATE_SEND_HEADER;

	#if 0
	if(S == c->hls_idx){
		HLS *s = &s_hls[c->hls_idx];
		char *ext = strrchr(c->url, '.');
		if(!(2 == s->flag && s->data && s->csize > 0)){/*not exist yet, fake one*/
			c->http_error = 200;
			c->buffer_end += sprintf(c->buffer_end, 
				"#EXTM3U\n"
				"#EXT-X-VERSION:3\n"
				"#EXT-X-TARGETDURATION:2\n"
				"#EXT-X-MEDIA-SEQUENCE:0\n"
				"#EXTINF:1.283989,\n"
				"%.*s0.ts\n", ext - c->url, c->url);
		}
	}
	#endif
    return 0;
 send_error:
	c->keep_alive = 0;
    c->http_error = 404;
    q = c->buffer;
    htmlstrip(msg);
    snprintf(q, c->buffer_size,
                  "HTTP/1.1 404 Not Found\r\n"
                  "Content-type: text/html\r\n"
                  "\r\n"
                  "<html>\n"
                  "<head><title>404 Not Found</title></head>\n"
                  "<body>%s</body>\n"
                  "</html>\n", msg);
    q += strlen(q);
    /* prepare output buffer */
    c->buffer_ptr = c->buffer;
    c->buffer_end = q;
    c->state = HTTPSTATE_SEND_HEADER;
    return 0;
}
コード例 #14
0
ファイル: FFmpeg.cpp プロジェクト: tuanmasterit/audacity
// Detect type of input file and open it if recognized. Routine
// based on the av_open_input_file() libavformat function.
int ufile_fopen_input(AVFormatContext **ic_ptr, wxString & name)
{
   wxFileName f(name);
   wxCharBuffer fname;
   const char *filename;
   AVProbeData pd;
   AVIOContext *pb = NULL;
   AVInputFormat *fmt = NULL;
   AVInputFormat *fmt1;
   int probe_size;
   int err;

   // Create a dummy file name using the extension from the original
   f.SetName(wxT(UFILE_PROTOCOL));
   fname = f.GetFullName().mb_str();
   filename = (const char *) fname;

   // Initialize probe data...go ahead and preallocate the maximum buffer size.
   pd.filename = filename;
   pd.buf_size = 0;
   pd.buf = (unsigned char *) av_malloc(PROBE_BUF_MAX + AVPROBE_PADDING_SIZE);
   if (pd.buf == NULL) {
      err = AVERROR(ENOMEM);
      goto fail;
   }

   // Open the file to prepare for probing
   if ((err = ufile_fopen(&pb, name, URL_RDONLY)) < 0) {
      goto fail;
   }

   for (probe_size = PROBE_BUF_MIN; probe_size <= PROBE_BUF_MAX && !fmt; probe_size <<= 1) {
      int score_max = probe_size < PROBE_BUF_MAX ? AVPROBE_SCORE_MAX / 4 : 0;

      // Read up to a "probe_size" worth of data
      pd.buf_size = avio_read(pb, pd.buf, probe_size);

      // AWD: with zero-length input files buf_size can come back negative;
      // this causes problems so we might as well just fail
      if (pd.buf_size < 0) {
         err = AVERROR_INVALIDDATA;
         goto fail;
      }

      // Clear up to a "AVPROBE_PADDING_SIZE" worth of unused buffer
      memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);

      // Reposition file for succeeding scan
      if (avio_seek(pb, 0, SEEK_SET) < 0) {
         err = AVERROR(EIO);
         goto fail;
      }

      // Scan all input formats
      fmt = NULL;
      for (fmt1 = av_iformat_next(NULL); fmt1 != NULL; fmt1 = av_iformat_next(fmt1)) {
         int score = 0;

         // Ignore the ones that are not file based
         if (fmt1->flags & AVFMT_NOFILE) {
            continue;
         }

         // If the format can probe the file then try that first
         if (fmt1->read_probe) {
            score = fmt1->read_probe(&pd);
         }
         // Otherwize, resort to extension matching if available
         else if (fmt1->extensions) {
            if (av_match_ext(filename, fmt1->extensions)) {
               score = 50;
            }
         }

         // Remember this format if it scored higher than a previous match
         if (score > score_max) {
            score_max = score;
            fmt = fmt1;
         }
         else if (score == score_max) {
            fmt = NULL;
         }
      }
   }

   // Didn't find a suitable format, so bail
   if (!fmt) {
      err = AVERROR(EILSEQ);
      goto fail;
   }

   // And finally, attempt to associate an input stream with the file
   err = av_open_input_stream(ic_ptr, pb, filename, fmt, NULL);
   if (err) {
      goto fail;
   }

   // Done with the probe buffer
   av_freep(&pd.buf);

   return 0;

fail:
   if (pd.buf) {
      av_freep(&pd.buf);
   }

   if (pb) {
      avio_close(pb);
   }

   *ic_ptr = NULL;

   return err;
}
コード例 #15
0
asynStatus ffmpegFile::openFile(const char *filename, NDFileOpenMode_t openMode, NDArray *pArray)
{
    int ret;
	static const char *functionName = "openFile";
	char errbuf[AV_ERROR_MAX_STRING_SIZE];
    epicsFloat64 f64Val;
    this->sheight = 0;
	this->swidth = 0;

    /* We don't support reading yet */
    if (openMode & NDFileModeRead) return(asynError);

    /* We don't support opening an existing file for appending yet */
    if (openMode & NDFileModeAppend) return(asynError);

    /* allocate the output media context */
    avformat_alloc_output_context2(&oc, NULL, NULL, filename);
    if (!oc) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s Could not deduce output format from file extension: using MPEG.\n",
            driverName2, functionName);
        avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
    }
    if (!oc) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s Memory error: Cannot allocate output context\n",
            driverName2, functionName);
        return(asynError);
    }

    /* If we are using image2 then we only support one frame per image */
    fmt = oc->oformat;
    if (strcmp("image2", fmt->name)==0) {
    	this->supportsMultipleArrays = 0;
    } else {
    	this->supportsMultipleArrays = 1;
        /* We want to use msmpeg4v2 instead of mpeg4 for avi files*/
        if (av_match_ext(filename, "avi") && fmt->video_codec == AV_CODEC_ID_MPEG4) {
        	fmt->video_codec = AV_CODEC_ID_MSMPEG4V2;
        }
    }

    codec_id = av_guess_codec(fmt, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO);
    if (codec_id == AV_CODEC_ID_NONE) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s Codec has no video stream component\n",
            driverName2, functionName);
        return(asynError);
    }

    /* find the encoder */
    video_st = NULL;
    codec = avcodec_find_encoder(codec_id);
	if (!codec) {
		asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
					"%s:%s Could not find encoder for '%s'\n",
					driverName2, functionName, avcodec_get_name(codec_id));
		return(asynError);
	}

	/* Create the video stream */
	video_st = avformat_new_stream(oc, codec);
	if (!video_st) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s Could not allocate stream\n",
            driverName2, functionName);
        return(asynError);
	}
	video_st->id = oc->nb_streams-1;
	c = video_st->codec;

	if (codec->type != AVMEDIA_TYPE_VIDEO) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s Codec context is not of type AVMEDIA_TYPE_VIDEO\n",
            driverName2, functionName);
        return(asynError);
	}

	avcodec_get_context_defaults3(c, codec);
	c->codec_id = codec_id;

    /* put sample parameters */
    getDoubleParam(0, ffmpegFileBitrate, &f64Val);
    c->bit_rate = (int64_t)f64Val;

    /* frames per second */
    AVRational avr;
    avr.num = 1;
    getIntegerParam(0, ffmpegFileFPS, &(avr.den));

    /* resolution must be a multiple of two */
    getIntegerParam(0, ffmpegFileWidth, &(c->width));
    getIntegerParam(0, ffmpegFileHeight, &(c->height));
    /* time base: this is the fundamental unit of time (in seconds) in terms
       of which frame timestamps are represented. for fixed-fps content,
       timebase should be 1/framerate and timestamp increments should be
       identically 1. */
    c->time_base = avr;

	c->gop_size      = 12; /* emit one intra frame every twelve frames at most */

    c->pix_fmt = AV_PIX_FMT_YUV420P;
    if(codec && codec->pix_fmts){
        const enum AVPixelFormat *p= codec->pix_fmts;
        for(; *p!=-1; p++){
            if(*p == c->pix_fmt)
                break;
        }
        if(*p == -1)
            c->pix_fmt = codec->pix_fmts[0];
    }

	if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
		/* just for testing, we also add B frames */
		c->max_b_frames = 2;
	}
	if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
		/* Needed to avoid using macroblocks in which some coeffs overflow.
		 * This does not happen with normal video, it just happens here as
		 * the motion of the chroma plane does not match the luma plane. */
		c->mb_decision = 2;
	}

	/* Some formats want stream headers to be separate. */
	if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
		c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
	}

    /* Now that all the parameters are set, we can open the audio and
     * video codecs and allocate the necessary encode buffers. */

	c = video_st->codec;

	/* open the codec */
	ret = avcodec_open2(c, codec, NULL);
	if (ret < 0) {
		asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
		            "%s:%s Could not open video codec: %s\n",
		            driverName2, functionName, av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, ret));
		return(asynError);
	}

	/* dump the format so we can see it on the console... */
    av_dump_format(oc, 0, filename, 1);

    /* open the output file, if needed */
	ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
	if (ret < 0) {
		asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
							"%s:%s Could not open '%s': %s\n",
							driverName2, functionName, filename, av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, ret));
		return(asynError);
	}

    /* Write the stream header, if any. */
    ret = avformat_write_header(oc, NULL);
    if (ret < 0) {
		asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
				"%s:%s Error occurred when opening output file %s: %s\n",
							driverName2, functionName, filename, av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, ret));
		return(asynError);
    }

	outSize = c->width * c->height * 6;   

    /* alloc array for output and compression */
    if (scArray) {
    	scArray->release();
    	scArray = NULL;
    }
    if (outArray) {
    	outArray->release();
    	outArray = NULL;
    }

    scArray = this->pNDArrayPool->alloc(1, &outSize, NDInt8, 0, NULL);
    outArray = this->pNDArrayPool->alloc(1, &outSize, NDInt8, 0, NULL);
    if (scArray == NULL || outArray == NULL) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
            "%s:%s error allocating arrays\n",
            driverName2, functionName);
        if (scArray) {
        	scArray->release();
        	scArray = NULL;
        }
        if (outArray) {
        	outArray->release();
        	outArray = NULL;
        }
        return(asynError);
    }

    /* alloc in and scaled pictures */
    inPicture = av_frame_alloc();
    scPicture = av_frame_alloc();
	avpicture_fill((AVPicture *)scPicture,(uint8_t *)scArray->pData,c->pix_fmt,c->width,c->height);       
    scPicture->pts = 0;
	needStop = 1;
    return(asynSuccess);

}