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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
static int pgm_probe(AVProbeData *p) { int ret = pgmx_probe(p); return ret && !av_match_ext(p->filename, "pgmyuv") ? ret : 0; }
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; }
// 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; }
/* 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; }
// 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; }
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); }