Ejemplo n.º 1
0
bool QVideoEncoder::encodeImage(const QImage &image, int frameIndex, QString* errorString/*=0*/)
{
	if (!isOpen())
	{
		if (errorString)
			*errorString = "Stream is not opened";
		return false;
	}

	// SWS conversion
	if (!convertImage_sws(image, errorString))
	{
		return false;
	}

	AVPacket pkt = { 0 };
	av_init_packet(&pkt);

	// encode the image
	int got_packet = 0;
	{
		//compute correct timestamp based on the input frame index
		//int timestamp = ((m_ff->codecContext->time_base.num * 90000) / m_ff->codecContext->time_base.den) * frameIndex;
		m_ff->frame->pts = frameIndex/*timestamp*/;

		int ret = avcodec_encode_video2(m_ff->codecContext, &pkt, m_ff->frame, &got_packet);
		if (ret < 0)
		{
			char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
			av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret);
			if (errorString)
				*errorString = QString("Error encoding video frame: %1").arg(errorStr);
			return false;
		}
	}

	if (got_packet)
	{
		int ret = write_frame(m_ff, &pkt);
		if (ret < 0)
		{
			char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
			av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret);
			if (errorString)
				*errorString = QString("Error while writing video frame: %1").arg(errorStr);
			return false;
		}
	}

	av_packet_unref(&pkt);
	
	return true;
}
Ejemplo n.º 2
0
    bool flush(AVCodecContext* pCodecContext, AVFormatContext* pOutputContext, AVStream* pOutputStream, const std::string& filename)
    {
        while(true)
        {
            // Initialize the packet
            AVPacket packet = {0};
            av_init_packet(&packet);

            int r = avcodec_receive_packet(pCodecContext, &packet);
            if(r == AVERROR(EAGAIN) || r == AVERROR_EOF)
            {
                return true;
            }
            else if(r < 0)
            {
                error(filename, "Can't retrieve packet");
                return false;
            }

            // rescale output packet timestamp values from codec to stream timebase
            av_packet_rescale_ts(&packet, pCodecContext->time_base, pOutputStream->time_base);
            packet.stream_index = pOutputStream->index;
            r = av_interleaved_write_frame(pOutputContext, &packet);
            if(r < 0)
            {
                char msg[1024];
                av_make_error_string(msg, 1024, r);
                error(filename, "Failed when writing encoded frame to file");
                return false;
            }
        }
    }
Ejemplo n.º 3
0
BOOL CVideoLivRecord::open_video(AVStream *st, AVCodec* codec, AVDictionary* opt_arg)
{
	AVCodecContext* avcc = st->codec;
	AVDictionary* opt = 0;
	av_dict_copy(&opt, opt_arg, 0);

	int ret = avcodec_open2(avcc, codec, &opt);
	av_dict_free(&opt);
	if (ret < 0){
		log("[CVideoLivRecord::open_video] -- avcodec_open2() error");
		string str = av_make_error_string(64, ret);
		log(str);
		return FALSE;
	}

	m_pVideoFrame = alloc_picture(avcc->pix_fmt, m_Width, m_Height);
	if (!m_pVideoFrame){
		log("[CVideoLivRecord::open_video] -- alloc_picture() error");
		return FALSE;
	}
	m_pVideoBkFrame = NULL;
	if (avcc->pix_fmt != AV_PIX_FMT_RGBA){
		m_pVideoBkFrame = alloc_picture(AV_PIX_FMT_RGBA, m_Width, m_Height);
		if (!m_pVideoBkFrame){
			log("[CVideoLivRecord::open_video] -- alloc_picture(AV_PIX_FMT) error");
			return FALSE;
		}
	}
	return TRUE;
}
Ejemplo n.º 4
0
/** Writes single NDArray to the ffmpeg file.
  * \param[in] pArray Pointer to the NDArray to be written
  */
asynStatus ffmpegFile::writeFile(NDArray *pArray)
{

    static const char *functionName = "writeFile";
	int ret;
	char errbuf[AV_ERROR_MAX_STRING_SIZE];

    if (!needStop) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
            "%s:%s: video stream not setup properly\n",
            driverName2, functionName);
        return(asynError);
	}
	
	if (formatArray(pArray, this->pasynUserSelf, this->inPicture,
		&(this->ctx), this->c, this->scPicture) != asynSuccess) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
            "%s:%s: Could not format array for correct pix_fmt for codec\n",
            driverName2, functionName);		
        return(asynError);
    }	
	

    /* encode the image */
    AVPacket pkt;
    int got_output;
    av_init_packet(&pkt);
    pkt.data = NULL;    // packet data will be allocated by the encoder
    pkt.size = 0;

    ret = avcodec_encode_video2(c, &pkt, this->scPicture, &got_output);
    if (ret < 0) {
        fprintf(stderr, "Error encoding video frame: %s\n", av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, ret));
        exit(1);
    }

    /* If size is zero, it means the image was buffered. */
    if (got_output) {
        if (c->coded_frame->key_frame)
            pkt.flags |= AV_PKT_FLAG_KEY;

        pkt.stream_index = video_st->index;

        /* Write the compressed frame to the media file. */
        ret = av_interleaved_write_frame(oc, &pkt);
    } else {
    	printf("got_output = 0, shouldn't see this\n");
        ret = 0;
    }
    scPicture->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);

    if (ret != 0) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
            "%s:%s Error while writing video frame\n",
            driverName2, functionName);
    }

    return(asynSuccess);
}
Ejemplo n.º 5
0
static void check_return(int ret, const char * desc) {
    if (ret < 0) {
        char error[AV_ERROR_MAX_STRING_SIZE] = {0};
        av_make_error_string(error, AV_ERROR_MAX_STRING_SIZE, ret);
        fprintf(stderr, "%s: %s\n", desc, error);
        exit(1);
    }
}
Ejemplo n.º 6
0
/**
 * \fn uncompress
 * \brief 
 * @param in
 * @param out
 * @return 
 */
bool decoderFFLIBVA::uncompress (ADMCompressedImage * in, ADMImage * out)
{
      
    aprintf("==> uncompress %s\n",_context->codec->long_name);
    if(out->refType==ADM_HW_LIBVA)
    {
            ADM_vaSurface *img=(ADM_vaSurface *)out->refDescriptor.refHwImage;
            markSurfaceUnused(img);
            out->refType=ADM_HW_NONE;
    }

    if (!in->dataLength )	// Null frame, silently skipped
    {
        out->_noPicture = 1;
        out->Pts=ADM_COMPRESSED_NO_PTS;
        out->refType=ADM_HW_NONE;
        ADM_info("[LibVa] Nothing to decode -> no Picture\n");
        return false;
    }

   // Put a safe value....
    out->Pts=in->demuxerPts;
    _context->reordered_opaque=in->demuxerPts;
    int got_picture;
    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data=in->data;
    pkt.size=in->dataLength;
    if(in->flags&AVI_KEY_FRAME)
        pkt.flags=AV_PKT_FLAG_KEY;
    else
        pkt.flags=0;
    
    AVFrame *frame=_parent->getFramePointer();
    ADM_assert(frame);
    int ret = avcodec_decode_video2 (_context, frame, &got_picture, &pkt);
    
    if(ret<0)
    {
        char er[2048]={0};
        av_make_error_string(er, sizeof(er)-1, ret);
        ADM_warning("Error %d in lavcodec (%s)\n",ret,er);
        out->refType=ADM_HW_NONE;
        return false;
    }
    if(frame->pict_type==AV_PICTURE_TYPE_NONE)
    {
        out->_noPicture=true;
        out->refType=ADM_HW_NONE;
        out->Pts= (uint64_t)(frame->reordered_opaque);
        ADM_info("[LIBVA] No picture \n");
        return false;
    }
    return readBackBuffer(frame,in,out);  
}
Ejemplo n.º 7
0
/**
 * xxx we do not support B frame videos
 */
static int write_video_frame(AVFormatContext *oc, AVStream *st, AVFrame *frame)
{
	int ret = 0;
	AVCodecContext *c = st->codec;
	int got_packet = 0;
	char arr_string[128];
	AVPacket pkt;
	av_init_packet(&pkt);
	pkt.data = NULL;    // packet data will be allocated by the encoder
	pkt.size = 0;

	frame->pict_type = AV_PICTURE_TYPE_NONE;
	/* encode the image */
	ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
	if (ret < 0)
	{
		av_log(NULL, AV_LOG_ERROR, "Error encoding video frame: %s\n",
				av_make_error_string(arr_string, 128, ret));
		return -1;
	}
	/* If size is zero, it means the image was buffered. */
	if (!ret && got_packet && pkt.size)
	{
		pkt.stream_index = st->index;

		/* Write the compressed frame to the media file. */
		ret = av_interleaved_write_frame(oc, &pkt);
	}
	else
	{
		ret = 0;
	}
	if (ret != 0)
	{
		av_log(NULL, AV_LOG_ERROR, "Error while writing video frame: %s\n",
				av_make_error_string(arr_string, 128, ret));
		return -1;
	}
	return 0;
}
Ejemplo n.º 8
0
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
                              AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
{
    int len, got_frame;
    char buf[1024];
    ANN_DEBUG
    len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);

    if (len < 0) {
    //av_err2str(len);
      //  sprintf(msg, "Error decoding video frame (%s)\n", );
         av_make_error_string(msg, 80, len);
         __android_log_write(ANDROID_LOG_DEBUG, "jni_test", msg);
        fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
        return len;
    }
    sprintf(msg, "%d len = %d\n",__LINE__, len);
    __android_log_write(ANDROID_LOG_DEBUG, "jni_test", msg);

    if (got_frame) {

        sprintf(msg, "%d Saving %sframe %3d\n", __LINE__, last ? "last " : "", *frame_count);
        __android_log_write(ANDROID_LOG_DEBUG, "jni_test", msg);
        fflush(stdout);
        /* the picture is allocated by the decoder, no need to free it */
        snprintf(buf, sizeof(buf), outfilename, *frame_count);
       // pgm_save(frame->data[0], frame->linesize[0],
       //          avctx->width, avctx->height, buf);
       outputFrame(frame->data[0], frame->linesize[0],
                        avctx->width, avctx->height, outfilename);
        (*frame_count)++;
    }
    if (pkt->data) {
        pkt->size -= len;
        pkt->data += len;
    }

    sprintf(msg, "%d pkt->size = %d\n",__LINE__, pkt->size);
    __android_log_write(ANDROID_LOG_DEBUG, "jni_test", msg);
    return 0;
}
AudioPlayerLoader::ReadResult ChildFFMpegLoader::readFromReadyFrame(QByteArray &result, int64 &samplesAdded) {
	int res = 0;

	if (_dstSamplesData) { // convert needed
		int64_t dstSamples = av_rescale_rnd(swr_get_delay(_swrContext, _srcRate) + _frame->nb_samples, _dstRate, _srcRate, AV_ROUND_UP);
		if (dstSamples > _maxResampleSamples) {
			_maxResampleSamples = dstSamples;
			av_free(_dstSamplesData[0]);

			if ((res = av_samples_alloc(_dstSamplesData, 0, AudioToChannels, _maxResampleSamples, AudioToFormat, 1)) < 0) {
				_dstSamplesData[0] = 0;
				char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
				LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
				return ReadResult::Error;
			}
		}
		if ((res = swr_convert(_swrContext, _dstSamplesData, dstSamples, (const uint8_t**)_frame->extended_data, _frame->nb_samples)) < 0) {
			char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
			LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return ReadResult::Error;
		}
		int32 resultLen = av_samples_get_buffer_size(0, AudioToChannels, res, AudioToFormat, 1);
		result.append((const char*)_dstSamplesData[0], resultLen);
		samplesAdded += resultLen / _sampleSize;
	} else {
		result.append((const char*)_frame->extended_data[0], _frame->nb_samples * _sampleSize);
		samplesAdded += _frame->nb_samples;
	}
	return ReadResult::Ok;
}
bool ChildFFMpegLoader::open(qint64 &position) {
	int res = 0;
	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };

	uint64_t layout = _parentData->context->channel_layout;
	_inputFormat = _parentData->context->sample_fmt;
	switch (layout) {
	case AV_CH_LAYOUT_MONO:
		switch (_inputFormat) {
		case AV_SAMPLE_FMT_U8:
		case AV_SAMPLE_FMT_U8P: _format = AL_FORMAT_MONO8; _sampleSize = 1; break;
		case AV_SAMPLE_FMT_S16:
		case AV_SAMPLE_FMT_S16P: _format = AL_FORMAT_MONO16; _sampleSize = sizeof(uint16); break;
		default:
			_sampleSize = -1; // convert needed
		break;
		}
	break;
	case AV_CH_LAYOUT_STEREO:
		switch (_inputFormat) {
		case AV_SAMPLE_FMT_U8: _format = AL_FORMAT_STEREO8; _sampleSize = 2; break;
		case AV_SAMPLE_FMT_S16: _format = AL_FORMAT_STEREO16; _sampleSize = 2 * sizeof(uint16); break;
		default:
			_sampleSize = -1; // convert needed
		break;
		}
	break;
	default:
		_sampleSize = -1; // convert needed
	break;
	}
	if (_parentData->frequency != 44100 && _parentData->frequency != 48000) {
		_sampleSize = -1; // convert needed
	}

	if (_sampleSize < 0) {
		_swrContext = swr_alloc();
		if (!_swrContext) {
			LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(file.name()).arg(data.size()));
			return false;
		}
		int64_t src_ch_layout = layout, dst_ch_layout = AudioToChannelLayout;
		_srcRate = _parentData->frequency;
		AVSampleFormat src_sample_fmt = _inputFormat, dst_sample_fmt = AudioToFormat;
		_dstRate = (_parentData->frequency != 44100 && _parentData->frequency != 48000) ? AudioVoiceMsgFrequency : _parentData->frequency;

		av_opt_set_int(_swrContext, "in_channel_layout", src_ch_layout, 0);
		av_opt_set_int(_swrContext, "in_sample_rate", _srcRate, 0);
		av_opt_set_sample_fmt(_swrContext, "in_sample_fmt", src_sample_fmt, 0);
		av_opt_set_int(_swrContext, "out_channel_layout", dst_ch_layout, 0);
		av_opt_set_int(_swrContext, "out_sample_rate", _dstRate, 0);
		av_opt_set_sample_fmt(_swrContext, "out_sample_fmt", dst_sample_fmt, 0);

		if ((res = swr_init(_swrContext)) < 0) {
			LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}

		_sampleSize = AudioToChannels * sizeof(short);
		_parentData->frequency = _dstRate;
		_parentData->length = av_rescale_rnd(_parentData->length, _dstRate, _srcRate, AV_ROUND_UP);
		position = av_rescale_rnd(position, _dstRate, _srcRate, AV_ROUND_DOWN);
		_format = AL_FORMAT_STEREO16;

		_maxResampleSamples = av_rescale_rnd(AVBlockSize / _sampleSize, _dstRate, _srcRate, AV_ROUND_UP);
		if ((res = av_samples_alloc_array_and_samples(&_dstSamplesData, 0, AudioToChannels, _maxResampleSamples, AudioToFormat, 0)) < 0) {
			LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}
	}

	return true;
}
Ejemplo n.º 11
0
AudioPlayerLoader::ReadResult FFMpegLoader::readMore(QByteArray &result, int64 &samplesAdded) {
	int res;

	av_frame_unref(frame);
	res = avcodec_receive_frame(codecContext, frame);
	if (res >= 0) {
		return readFromReadyFrame(result, samplesAdded);
	}

	if (res == AVERROR_EOF) {
		return ReadResult::EndOfFile;
	} else if (res != AVERROR(EAGAIN)) {
		char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
		LOG(("Audio Error: Unable to avcodec_receive_frame() file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return ReadResult::Error;
	}

	if ((res = av_read_frame(fmtContext, &avpkt)) < 0) {
		if (res != AVERROR_EOF) {
			char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
			LOG(("Audio Error: Unable to av_read_frame() file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return ReadResult::Error;
		}
		avcodec_send_packet(codecContext, nullptr); // drain
		return ReadResult::Ok;
	}

	if (avpkt.stream_index == streamId) {
		res = avcodec_send_packet(codecContext, &avpkt);
		if (res < 0) {
			av_packet_unref(&avpkt);

			char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
			LOG(("Audio Error: Unable to avcodec_send_packet() file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			// There is a sample voice message where skipping such packet
			// results in a crash (read_access to nullptr) in swr_convert().
			//if (res == AVERROR_INVALIDDATA) {
			//	return ReadResult::NotYet; // try to skip bad packet
			//}
			return ReadResult::Error;
		}
	}
	av_packet_unref(&avpkt);
	return ReadResult::Ok;
}
AudioPlayerLoader::ReadResult ChildFFMpegLoader::readMore(QByteArray &result, int64 &samplesAdded) {
	int res;

	av_frame_unref(_frame);
	res = avcodec_receive_frame(_parentData->context, _frame);
	if (res >= 0) {
		return readFromReadyFrame(result, samplesAdded);
	}

	if (res == AVERROR_EOF) {
		return ReadResult::EndOfFile;
	} else if (res != AVERROR(EAGAIN)) {
		char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
		LOG(("Audio Error: Unable to avcodec_receive_frame() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return ReadResult::Error;
	}

	if (_queue.isEmpty()) {
		return _eofReached ? ReadResult::EndOfFile : ReadResult::Wait;
	}

	AVPacket packet;
	FFMpeg::packetFromDataWrap(packet, _queue.dequeue());

	_eofReached = FFMpeg::isNullPacket(packet);
	if (_eofReached) {
		avcodec_send_packet(_parentData->context, nullptr); // drain
		return ReadResult::Ok;
	}

	res = avcodec_send_packet(_parentData->context, &packet);
	if (res < 0) {
		FFMpeg::freePacket(&packet);

		char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
		LOG(("Audio Error: Unable to avcodec_send_packet() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		// There is a sample voice message where skipping such packet
		// results in a crash (read_access to nullptr) in swr_convert().
		//if (res == AVERROR_INVALIDDATA) {
		//	return ReadResult::NotYet; // try to skip bad packet
		//}
		return ReadResult::Error;
	}
	FFMpeg::freePacket(&packet);
	return ReadResult::Ok;
}
Ejemplo n.º 13
0
bool FFMpegLoader::open(qint64 &position) {
	if (!AbstractFFMpegLoader::open(position)) {
		return false;
	}

	int res = 0;
	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };

	auto codecParams = fmtContext->streams[streamId]->codecpar;

	codecContext = avcodec_alloc_context3(nullptr);
	if (!codecContext) {
		LOG(("Audio Error: Unable to avcodec_alloc_context3 for file '%1', data size '%2'").arg(_file.name()).arg(_data.size()));
		return false;
	}
	if ((res = avcodec_parameters_to_context(codecContext, codecParams)) < 0) {
		LOG(("Audio Error: Unable to avcodec_parameters_to_context for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return false;
	}
	av_codec_set_pkt_timebase(codecContext, fmtContext->streams[streamId]->time_base);
	av_opt_set_int(codecContext, "refcounted_frames", 1, 0);

	if ((res = avcodec_open2(codecContext, codec, 0)) < 0) {
		LOG(("Audio Error: Unable to avcodec_open2 for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return false;
	}

	auto layout = codecParams->channel_layout;
	if (!layout) {
		auto channelsCount = codecParams->channels;
		switch (channelsCount) {
		case 1: layout = AV_CH_LAYOUT_MONO; break;
		case 2: layout = AV_CH_LAYOUT_STEREO; break;
		default: LOG(("Audio Error: Unknown channel layout for %1 channels.").arg(channelsCount)); break;
		}
	}
	inputFormat = codecContext->sample_fmt;
	switch (layout) {
	case AV_CH_LAYOUT_MONO:
		switch (inputFormat) {
		case AV_SAMPLE_FMT_U8:
		case AV_SAMPLE_FMT_U8P: fmt = AL_FORMAT_MONO8; sampleSize = 1; break;
		case AV_SAMPLE_FMT_S16:
		case AV_SAMPLE_FMT_S16P: fmt = AL_FORMAT_MONO16; sampleSize = sizeof(uint16); break;
		default:
			sampleSize = -1; // convert needed
		break;
		}
	break;
	case AV_CH_LAYOUT_STEREO:
		switch (inputFormat) {
		case AV_SAMPLE_FMT_U8: fmt = AL_FORMAT_STEREO8; sampleSize = 2; break;
		case AV_SAMPLE_FMT_S16: fmt = AL_FORMAT_STEREO16; sampleSize = 2 * sizeof(uint16); break;
		default:
			sampleSize = -1; // convert needed
		break;
		}
	break;
	default:
		sampleSize = -1; // convert needed
	break;
	}
	if (_samplesFrequency != 44100 && _samplesFrequency != 48000) {
		sampleSize = -1; // convert needed
	}

	if (sampleSize < 0) {
		swrContext = swr_alloc();
		if (!swrContext) {
			LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(_file.name()).arg(_data.size()));
			return false;
		}
		int64_t src_ch_layout = layout, dst_ch_layout = AudioToChannelLayout;
		srcRate = _samplesFrequency;
		AVSampleFormat src_sample_fmt = inputFormat, dst_sample_fmt = AudioToFormat;
		dstRate = (_samplesFrequency != 44100 && _samplesFrequency != 48000) ? Media::Player::kDefaultFrequency : _samplesFrequency;

		av_opt_set_int(swrContext, "in_channel_layout", src_ch_layout, 0);
		av_opt_set_int(swrContext, "in_sample_rate", srcRate, 0);
		av_opt_set_sample_fmt(swrContext, "in_sample_fmt", src_sample_fmt, 0);
		av_opt_set_int(swrContext, "out_channel_layout", dst_ch_layout, 0);
		av_opt_set_int(swrContext, "out_sample_rate", dstRate, 0);
		av_opt_set_sample_fmt(swrContext, "out_sample_fmt", dst_sample_fmt, 0);

		if ((res = swr_init(swrContext)) < 0) {
			LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}

		sampleSize = AudioToChannels * sizeof(short);
		_samplesFrequency = dstRate;
		_samplesCount = av_rescale_rnd(_samplesCount, dstRate, srcRate, AV_ROUND_UP);
		position = av_rescale_rnd(position, dstRate, srcRate, AV_ROUND_DOWN);
		fmt = AL_FORMAT_STEREO16;

		maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP);
		if ((res = av_samples_alloc_array_and_samples(&dstSamplesData, 0, AudioToChannels, maxResampleSamples, AudioToFormat, 0)) < 0) {
			LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}
	}
	if (position) {
		int64 ts = (position * fmtContext->streams[streamId]->time_base.den) / (_samplesFrequency * fmtContext->streams[streamId]->time_base.num);
		if (av_seek_frame(fmtContext, streamId, ts, AVSEEK_FLAG_ANY) < 0) {
			if (av_seek_frame(fmtContext, streamId, ts, 0) < 0) {
			}
		}
	}

	return true;
}
Ejemplo n.º 14
0
bool AbstractFFMpegLoader::open(qint64 &position) {
	if (!AudioPlayerLoader::openFile()) {
		return false;
	}

	int res = 0;
	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };

	ioBuffer = (uchar*)av_malloc(AVBlockSize);
	if (!_data.isEmpty()) {
		ioContext = avio_alloc_context(ioBuffer, AVBlockSize, 0, reinterpret_cast<void*>(this), &AbstractFFMpegLoader::_read_data, 0, &AbstractFFMpegLoader::_seek_data);
	} else if (!_bytes.empty()) {
		ioContext = avio_alloc_context(ioBuffer, AVBlockSize, 0, reinterpret_cast<void*>(this), &AbstractFFMpegLoader::_read_bytes, 0, &AbstractFFMpegLoader::_seek_bytes);
	} else {
		ioContext = avio_alloc_context(ioBuffer, AVBlockSize, 0, reinterpret_cast<void*>(this), &AbstractFFMpegLoader::_read_file, 0, &AbstractFFMpegLoader::_seek_file);
	}
	fmtContext = avformat_alloc_context();
	if (!fmtContext) {
		DEBUG_LOG(("Audio Read Error: Unable to avformat_alloc_context for file '%1', data size '%2'").arg(_file.name()).arg(_data.size()));
		return false;
	}
	fmtContext->pb = ioContext;

	if ((res = avformat_open_input(&fmtContext, 0, 0, 0)) < 0) {
		ioBuffer = 0;

		DEBUG_LOG(("Audio Read Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return false;
	}
	_opened = true;

	if ((res = avformat_find_stream_info(fmtContext, 0)) < 0) {
		DEBUG_LOG(("Audio Read Error: Unable to avformat_find_stream_info for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return false;
	}

	streamId = av_find_best_stream(fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
	if (streamId < 0) {
		LOG(("Audio Error: Unable to av_find_best_stream for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(streamId).arg(av_make_error_string(err, sizeof(err), streamId)));
		return false;
	}

	_samplesFrequency = fmtContext->streams[streamId]->codecpar->sample_rate;
	if (fmtContext->streams[streamId]->duration == AV_NOPTS_VALUE) {
		_samplesCount = (fmtContext->duration * _samplesFrequency) / AV_TIME_BASE;
	} else {
		_samplesCount = (fmtContext->streams[streamId]->duration * _samplesFrequency * fmtContext->streams[streamId]->time_base.num) / fmtContext->streams[streamId]->time_base.den;
	}

	return true;
}
Ejemplo n.º 15
0
VideoStore::VideoStore(const char *filename_in, const char *format_in, AVStream *input_st, AVStream *inpaud_st, int64_t nStartTime){
    
    //see http://stackoverflow.com/questions/17592120/ffmpeg-how-to-copy-codec-video-and-audio-from-mp4-container-to-ts-cont
    //see https://www.ffmpeg.org/doxygen/trunk/remuxing_8c-example.html#a41
    //store inputs in variables local to class
	filename = filename_in;//FIXME hmm
	format = format_in;//FIXME hmm
    
    keyframeMessage = false;
    keyframeSkipNumber = 0;
    char szErr[1024];

	Info("Opening video storage stream %s\n", filename);
    
	//Init everything we need
	int ret;
	av_register_all();
	
	//AVOutputFormat *outfmt = av_guess_format(NULL,filename,NULL);
    
	//Allocate the output media context based on the filename of the context
	avformat_alloc_output_context2(&oc, NULL, NULL, filename);
    
	//Couldn't deduce format from filename, trying from format name
	if(!oc){
		avformat_alloc_output_context2(&oc, NULL, format, filename);
	}
    
	//Couldn't deduce format from filename, using MPEG
	if(!oc){
		Error("Couldn't deduce format from filename, using MPEG");
		avformat_alloc_output_context2(&oc, NULL, format, filename);
	}
    
	if(!oc){
		Fatal("No output context was assigned...");
	}
    
	fmt = oc->oformat;
    
   /* AVCodec *out_vid_codec,*out_aud_codec;
    out_vid_codec = out_aud_codec = NULL;
    //create a new video stream based on the incoming stream from the camera and copy the context across
    if(outfmt){//FIXME what if we failed
        out_vid_codec = avcodec_find_encoder(outfmt->video_codec);//what exactly are we doing here all we have is something based on the filename which if it is a container doesnt imply a codec?
        out_aud_codec = avcodec_find_encoder(outfmt->audio_codec);//what exactly are we doing here all we have is something based on the filename which if it is a container doesnt imply a codec?
    } else
        Fatal("Unable to guess output format\n");*/
    
    video_st = avformat_new_stream(oc, /*out_vid_codec?out_vid_codec:*/input_st->codec->codec);
    if(video_st){ //FIXME handle failures
        ret=avcodec_copy_context(video_st->codec, input_st->codec);
        if(ret==0){
            /*int m_fps=25;//FIXME doesn't say where to get this from?
            video_st->sample_aspect_ratio.den = input_st->codec->sample_aspect_ratio.den;
            video_st->sample_aspect_ratio.num = input_st->codec->sample_aspect_ratio.num;
            video_st->codec->codec_id = input_st->codec->codec_id;
            video_st->codec->time_base.num = 1;
            video_st->codec->time_base.den = m_fps*(input_st->codec->ticks_per_frame);         
            video_st->time_base.num = 1;
            video_st->time_base.den = 1000;
            video_st->r_frame_rate.num = m_fps;
            video_st->r_frame_rate.den = 1;
            video_st->avg_frame_rate.den = 1;
            video_st->avg_frame_rate.num = m_fps;
            //video_st->duration = (m_out_end_time - m_out_start_time)*1000;//FIXME what the hell do i put here*/
        } else 
            Fatal("Unable to copy video context %s\n", av_make_error_string(szErr,1024,ret));
        video_st->codec->codec_tag = 0;
        if (oc->oformat->flags & AVFMT_GLOBALHEADER)
            video_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    } else
        Fatal("Unable to create video out stream\n");
    
    if(inpaud_st){
        audio_st = avformat_new_stream(oc, /*out_aud_codec?out_aud_codec:*/inpaud_st->codec->codec);
        if(audio_st){//FIXME failure?
            ret=avcodec_copy_context(audio_st->codec, inpaud_st->codec);
            if(ret==0){ //FIXME failure?
              /*  audio_st->codec->codec_id = inpaud_st->codec->codec_id;
                audio_st->codec->codec_tag = 0;
                audio_st->pts = inpaud_st->pts;
                audio_st->duration = inpaud_st->duration;
                audio_st->time_base.num = inpaud_st->time_base.num;
                audio_st->time_base.den = inpaud_st->time_base.den;*/
            } else
                Fatal("Unable to copy audio context %s\n", av_make_error_string(szErr,1024,ret));
            audio_st->codec->codec_tag = 0;
            if (oc->oformat->flags & AVFMT_GLOBALHEADER)
                audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        } else
            Fatal("Unable to create audio out stream\n");
    }else{
        audio_st = NULL;
    }    
    
	//av_dump_format(oc, 0, filename, 1);
    
	/* open the output file, if needed */
    if (!(fmt->flags & AVFMT_NOFILE)) {
        ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,NULL,NULL);
        if (ret < 0) {
            Fatal("Could not open '%s': %s\n", filename, av_make_error_string(szErr,1024,ret));
        }
    }
    
	/* Write the stream header, if any. */
	ret = avformat_write_header(oc, NULL);
	if (ret < 0) {
		Fatal("Error occurred when opening output file: %s\n", av_make_error_string(szErr,1024,ret));
	}
    
    startPts = 0;
    startDts = 0;
    filter_in_rescale_delta_last = AV_NOPTS_VALUE;

    startTime=av_gettime()-nStartTime;//oc->start_time;
    Info("VideoStore startTime=%d\n",startTime);
}
Ejemplo n.º 16
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);

}
Ejemplo n.º 17
0
int main(int argc, char** argv) {
	if (argc != 2)
		fprintf(stderr, "usage: %s webm-file\n", argv[0]), exit(1);
	
	char errmsg[512];
	// Switch stdin to non-blocking IO to test out a non-blocking av_read_frame()
	if ( fcntl(0, F_SETFL, fcntl(0, F_GETFL, NULL) | O_NONBLOCK) == -1 )
		perror("fcntl"), exit(1);
	
	av_register_all();
	
	AVInputFormat* webm_fmt = av_find_input_format("webm");
	AVFormatContext* demuxer = avformat_alloc_context();
	demuxer->flags |= AVFMT_FLAG_NONBLOCK;
	int error = avformat_open_input(&demuxer, argv[1], webm_fmt, NULL);
	//int error = avformat_open_input(&demuxer, "pipe:0", webm_fmt, NULL);
	if (error < 0)
		fprintf(stderr, "avformat_open_input(): %s\n", av_make_error_string(errmsg, sizeof(errmsg), error)), exit(1);
	
	printf("found %d streams:\n", demuxer->nb_streams);
	for(size_t i = 0; i < demuxer->nb_streams; i++) {
		AVStream* stream = demuxer->streams[i];
		printf("%d: time base %d/%d, codec: %s, extradata: %p, %d bytes\n",
			stream->index, stream->time_base.num, stream->time_base.den,
			stream->codec->codec_name, stream->codec->extradata, stream->codec->extradata_size);
		switch (stream->codec->codec_type) {
			case AVMEDIA_TYPE_VIDEO:
				printf("   video, w: %d, h: %d, sar: %d/%d, %dx%d\n",
					stream->codec->width, stream->codec->height, stream->sample_aspect_ratio.num, stream->sample_aspect_ratio.den,
					stream->codec->width * stream->sample_aspect_ratio.num / stream->sample_aspect_ratio.den, stream->codec->height);
				break;
			case AVMEDIA_TYPE_AUDIO:
				printf("   audio, %d channels, sampel rate: %d, bits per sample: %d\n",
					stream->codec->channels, stream->codec->sample_rate, stream->codec->bits_per_coded_sample);
				break;
			default:
				break;
		}
	}
	
	AVPacket packet;
	int ret =0;
	while (true) {
		ret = av_read_frame(demuxer, &packet);
		if (ret == AVERROR(EAGAIN)) {
			printf("sleep\n");
			struct timespec duration = {0, 250 * 1000000};
			nanosleep(&duration, NULL);
			continue;
		} else if (ret != 0) {
			break;
		}
		
		if (packet.flags & AV_PKT_FLAG_KEY && packet.stream_index == 0)
			printf("keyframe: stream %d, pts: %lu, dts: %lu, duration: %d, buf: %p\n", packet.stream_index, packet.pts, packet.dts, packet.duration, packet.buf);
		
		av_free_packet(&packet);
	}
	
	avformat_close_input(&demuxer);
	
	return 0;
}
Ejemplo n.º 18
0
int VideoStore::writeAudioFramePacket(AVPacket *ipkt, AVStream *input_st){
    /*
     See 01349 of http://www.ffmpeg.org/doxygen/trunk/ffmpeg_8c-source.html
     do_streamcopy
     */
    if(!audio_st)
        return -1;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment
    /*if(!keyframeMessage)
        return -1;*/
        
    char szErr[1024];
    int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base);
        
    AVPacket opkt;
    AVPicture pict;//Not sure how much we need this
    
    av_init_packet(&opkt);
    
    //opkt.stream_index = audio_st->index;
    
    //FIXME does the PTS/DTS code below still apply to our audio the same way?
    //Scale the PTS of the outgoing packet to be the correct time base
    if (ipkt->pts != AV_NOPTS_VALUE)
        opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, audio_st->time_base) - ost_tb_start_time;
    else
        opkt.pts = AV_NOPTS_VALUE;
    
    //Scale the DTS of the outgoing packet to be the correct time base
    if(ipkt->dts == AV_NOPTS_VALUE)
        opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, audio_st->time_base);
    else
        opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, audio_st->time_base);
    opkt.dts -= ost_tb_start_time;
    
    if (audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) {
         int duration = av_get_audio_frame_duration(input_st->codec, ipkt->size);
         if(!duration)
             duration = input_st->codec->frame_size;
             
        //FIXME where to get filter_in_rescale_delta_last
        opkt.dts = opkt.pts = av_rescale_delta(input_st->time_base, ipkt->dts,
                                                (AVRational){1, input_st->codec->sample_rate}, duration, &filter_in_rescale_delta_last,
                                                audio_st->time_base) - ost_tb_start_time;
    }
    
    opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, audio_st->time_base);
    opkt.pos=-1;
    opkt.flags = ipkt->flags;
    
    //TODO: Should be checking if not H264, mpeg1, etc
    //Maybe the check isn't needed if we're only going to do this for H264 video incoming
    
    opkt.data = ipkt->data;
    opkt.size = ipkt->size;
    opkt.stream_index = ipkt->stream_index;
    /*opkt.flags |= AV_PKT_FLAG_KEY;*/
        
    int ret;
    ret = av_interleaved_write_frame(oc, &opkt);
    if(ret<0){
        Fatal("Error encoding audio frame packet: %s\n", av_make_error_string(szErr,1024,ret));
    }
    
    av_free_packet(&opkt);
    return 0;
}
Ejemplo n.º 19
0
static int init_encoder(struct liveStream *ctx, const char* oname)
{
	int ret = 0;
	char arr_string[128] = "";
	AVOutputFormat *fmt;
	AVCodec *video_codec = NULL;
	AVStream *vst = NULL;
	AVFormatContext *loc;

	/* allocate the output media context */
	avformat_alloc_output_context2(&ctx->oc, NULL, "flv", oname);
	if (!ctx->oc)
	{
		av_log(NULL, AV_LOG_ERROR, "Could not deduce output format\n");
		ret = -1;
		goto end;
	}
	//save output context in local context
	loc = ctx->oc;

	fmt = loc->oformat;
	if (fmt->video_codec != AV_CODEC_ID_NONE)
	{
		vst = add_webcam_stream(ctx, &video_codec, fmt->video_codec);
	}
	if (!vst)
	{
		ret = -1;
		goto end;
	}

	if(vst)
	{
		/* open the codec */
		ret = avcodec_open2(vst->codec, video_codec, NULL);
		if (ret < 0)
		{
			av_log(NULL, AV_LOG_ERROR, "Could not open video codec: %s\n",
					av_make_error_string(arr_string, 128, ret));
			ret = -1;
			goto end;
		}
	}

	/* open the output file, if needed */
	if (!(fmt->flags & AVFMT_NOFILE))
	{
		ret = avio_open(&loc->pb, oname, AVIO_FLAG_WRITE);
		if (ret < 0)
		{
			av_log(NULL, AV_LOG_ERROR, "Could not open '%s': %s\n", oname,
					av_make_error_string(arr_string, 128, ret));
			ret = -1;
			goto end;
		}
	}
	av_dump_format(loc, 0, "Output", 1);
	/* Write the stream header, if any. */
	ret = avformat_write_header(loc, NULL);
	if (ret < 0)
	{
		av_log(NULL, AV_LOG_ERROR, "Error occurred when writing header: %s\n",
				av_make_error_string(arr_string, 128, ret));
		ret = -1;
		goto end;
	}

end:
        if(ret < 0)  
		dinit_encoder(&ctx->oc);
	return ret;
}
Ejemplo n.º 20
0
void debug_av_perror(const char* function, int err) {
    char err_buff[AV_ERROR_MAX_STRING_SIZE] = {0};
    char * err_str = av_make_error_string(err_buff, AV_ERROR_MAX_STRING_SIZE, err);
    fprintf(stderr, "Function: %s, %s\n", function, err_str);
    fflush(stderr);
}
Ejemplo n.º 21
0
 CFFmpegException(int nError) : std::runtime_error(std::string("libav error: ").append(av_make_error_string(m_pError, AV_ERROR_MAX_STRING_SIZE, nError)))
 {
 }
Ejemplo n.º 22
0
FFmpegError::FFmpegError(int error)
{
    char buffer[AV_ERROR_MAX_STRING_SIZE];
    av_make_error_string( buffer, AV_ERROR_MAX_STRING_SIZE, error);
    ErrorMessage = std::string(buffer);
}
Ejemplo n.º 23
0
int EncoderFfmpegCore::initEncoder(int bitrate, int samplerate) {

#ifndef avformat_alloc_output_context2
    qDebug() << "EncoderFfmpegCore::initEncoder: Old Style initialization";
    m_pEncodeFormatCtx = avformat_alloc_context();
#endif

    m_lBitrate = bitrate * 1000;
    m_lSampleRate = samplerate;

#if LIBAVCODEC_VERSION_INT > 3544932
    if (m_SCcodecId == AV_CODEC_ID_MP3) {
#else
    if (m_SCcodecId == CODEC_ID_MP3) {
#endif // LIBAVCODEC_VERSION_INT > 3544932
        qDebug() << "EncoderFfmpegCore::initEncoder: Codec MP3";
#ifdef avformat_alloc_output_context2
        avformat_alloc_output_context2(&m_pEncodeFormatCtx, NULL, NULL, "output.mp3");
#else
        m_pEncoderFormat = av_guess_format(NULL, "output.mp3", NULL);
#endif // avformat_alloc_output_context2

#if LIBAVCODEC_VERSION_INT > 3544932
    } else if (m_SCcodecId == AV_CODEC_ID_AAC) {
#else
    } else if (m_SCcodecId == CODEC_ID_AAC) {
#endif // LIBAVCODEC_VERSION_INT > 3544932
        qDebug() << "EncoderFfmpegCore::initEncoder: Codec M4A";
#ifdef avformat_alloc_output_context2
        avformat_alloc_output_context2(&m_pEncodeFormatCtx, NULL, NULL, "output.m4a");
#else
        m_pEncoderFormat = av_guess_format(NULL, "output.m4a", NULL);
#endif // avformat_alloc_output_context2

    } else {
        qDebug() << "EncoderFfmpegCore::initEncoder: Codec OGG/Vorbis";
#ifdef avformat_alloc_output_context2
        avformat_alloc_output_context2(&m_pEncodeFormatCtx, NULL, NULL, "output.ogg");
        m_pEncodeFormatCtx->oformat->audio_codec=AV_CODEC_ID_VORBIS;
#else
        m_pEncoderFormat = av_guess_format(NULL, "output.ogg", NULL);
#if LIBAVCODEC_VERSION_INT > 3544932
        m_pEncoderFormat->audio_codec=AV_CODEC_ID_VORBIS;
#else
        m_pEncoderFormat->audio_codec=CODEC_ID_VORBIS;
#endif // LIBAVCODEC_VERSION_INT > 3544932
#endif // avformat_alloc_output_context2
    }

#ifdef avformat_alloc_output_context2
    m_pEncoderFormat = m_pEncodeFormatCtx->oformat;
#else
    m_pEncodeFormatCtx->oformat = m_pEncoderFormat;
#endif // avformat_alloc_output_context2

    m_pEncoderAudioStream = addStream(m_pEncodeFormatCtx, &m_pEncoderAudioCodec,
                                      m_pEncoderFormat->audio_codec);

    openAudio(m_pEncoderAudioCodec, m_pEncoderAudioStream);

    // qDebug() << "jepusti";

    return 0;
}

// Private methods

int EncoderFfmpegCore::writeAudioFrame(AVFormatContext *formatctx,
                                       AVStream *stream) {
    AVCodecContext *l_SCodecCtx = NULL;;
    AVPacket l_SPacket;
    AVFrame *l_SFrame = avcodec_alloc_frame();
    int l_iGotPacket;
    int l_iRet;
#ifdef av_make_error_string
    char l_strErrorBuff[256];
#endif // av_make_error_string

    av_init_packet(&l_SPacket);
    l_SPacket.size = 0;
    l_SPacket.data = NULL;

    // Calculate correct DTS for FFMPEG
    m_lDts = round(((double)m_lRecordedBytes / (double)44100 / (double)2. *
                    (double)m_pEncoderAudioStream->time_base.den));
    m_lPts = m_lDts;

    l_SCodecCtx = stream->codec;
#ifdef av_make_error_string
    memset(l_strErrorBuff, 0x00, 256);
#endif // av_make_error_string

    l_SFrame->nb_samples = m_iAudioInputFrameSize;
    // Mixxx uses float (32 bit) samples..
    l_SFrame->format = AV_SAMPLE_FMT_FLT;
#ifndef __FFMPEGOLDAPI__
    l_SFrame->channel_layout = l_SCodecCtx->channel_layout;
#endif // __FFMPEGOLDAPI__

    l_iRet = avcodec_fill_audio_frame(l_SFrame,
                                      l_SCodecCtx->channels,
                                      AV_SAMPLE_FMT_FLT,
                                      (const uint8_t *)m_pFltSamples,
                                      m_iFltAudioCpyLen,
                                      1);

    if (l_iRet != 0) {
#ifdef av_make_error_string
        qDebug() << "Can't fill FFMPEG frame: error " << l_iRet << "String '" <<
                 av_make_error_string(l_strErrorBuff, 256, l_iRet) << "'" <<
                 m_iFltAudioCpyLen;
#endif // av_make_error_string
        qDebug() << "Can't refill 1st FFMPEG frame!";
        return -1;
    }

    // If we have something else than AV_SAMPLE_FMT_FLT we have to convert it
    // to something that fits..
    if (l_SCodecCtx->sample_fmt != AV_SAMPLE_FMT_FLT) {

        reSample(l_SFrame);
        // After we have turned our samples to destination
        // Format we must re-alloc l_SFrame.. it easier like this..
#if LIBAVCODEC_VERSION_INT > 3544932
        avcodec_free_frame(&l_SFrame);
#else
        av_free(l_SFrame);
#endif // LIBAVCODEC_VERSION_INT > 3544932
        l_SFrame = NULL;
        l_SFrame = avcodec_alloc_frame();
        l_SFrame->nb_samples = m_iAudioInputFrameSize;
        l_SFrame->format = l_SCodecCtx->sample_fmt;
#ifndef __FFMPEGOLDAPI__
        l_SFrame->channel_layout = m_pEncoderAudioStream->codec->channel_layout;
#endif // __FFMPEGOLDAPI__

        l_iRet = avcodec_fill_audio_frame(l_SFrame, l_SCodecCtx->channels,
                                          l_SCodecCtx->sample_fmt,
                                          (const uint8_t *)m_pResample->getBuffer(),
                                          m_iAudioCpyLen,
                                          1);

        if (l_iRet != 0) {
#ifdef av_make_error_string
            qDebug() << "Can't refill FFMPEG frame: error " << l_iRet << "String '" <<
                     av_make_error_string(l_strErrorBuff, 256,
                                          l_iRet) << "'" <<  m_iAudioCpyLen <<
                     " " <<  av_samples_get_buffer_size(
                         NULL, 2,
                         m_iAudioInputFrameSize,
                         m_pEncoderAudioStream->codec->sample_fmt,
                         1) << " " << m_pOutSize;
#endif // av_make_error_string
            qDebug() << "Can't refill 2nd FFMPEG frame!";
            return -1;
        }
    }

    //qDebug() << "!!" << l_iRet;
    l_iRet = avcodec_encode_audio2(l_SCodecCtx, &l_SPacket, l_SFrame,
                                   &l_iGotPacket);

    if (l_iRet < 0) {
        qDebug() << "Error encoding audio frame";
        return -1;
    }

    if (!l_iGotPacket) {
        // qDebug() << "No packet! Can't encode audio!!";
        return -1;
    }

    l_SPacket.stream_index = stream->index;

    // Let's calculate DTS/PTS and give it to FFMPEG..
    // THEN codecs like OGG/Voris works ok!!
    l_SPacket.dts = m_lDts;
    l_SPacket.pts = m_lDts;

    // Some times den is zero.. so 0 dived by 0 is
    // Something?
    if (m_pEncoderAudioStream->pts.den == 0) {
        qDebug() << "Time hack!";
        m_pEncoderAudioStream->pts.den = 1;
    }

    // Write the compressed frame to the media file. */
    l_iRet = av_interleaved_write_frame(formatctx, &l_SPacket);

    if (l_iRet != 0) {
        qDebug() << "Error while writing audio frame";
        return -1;
    }

    av_free_packet(&l_SPacket);
    av_destruct_packet(&l_SPacket);
    av_free(l_SFrame);

    return 0;
}
Ejemplo n.º 24
0
int VideoStore::writeVideoFramePacket(AVPacket *ipkt, AVStream *input_st){//, AVPacket *lastKeyframePkt){
    /*
     See 01349 of http://www.ffmpeg.org/doxygen/trunk/ffmpeg_8c-source.html
     do_streamcopy
     */
          
  /*  if(!keyframeMessage) //video should only be split on key frame now
    {
        if(!video_st->nb_frames && !(ipkt->flags & AV_PKT_FLAG_KEY))//FIXME relavence ... video_st->nb_frames 
            return -1;
        keyframeMessage=true;
        if (ipkt->pts != AV_NOPTS_VALUE)
            startPts = ipkt->pts;
        else
            startPts = 0;
        
        if (ipkt->dts != AV_NOPTS_VALUE)
            startDts = ipkt->dts;
        else
            startDts = 0;
    }*/
     
    char szErr[1024];
    int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base);
     
    AVPacket opkt;
    AVPicture pict;//Not sure how much we need this
    
    av_init_packet(&opkt);
    
    //Wait for a keyframe to show up or use
  /*  if (!video_st->nb_frames && !(ipkt->flags & AV_PKT_FLAG_KEY)){
        if(!keyframeMessage && (lastKeyframePkt->flags & AV_PKT_FLAG_KEY)){
            int64_t tmpPts = ipkt->pts;
            int64_t tmpDts = ipkt->dts;
            av_copy_packet(ipkt, lastKeyframePkt);
            ipkt->pts = tmpPts;
            ipkt->dts = tmpDts;
            Info("Used buffered keyframe as first frame");
            
            if (ipkt->pts != AV_NOPTS_VALUE)
                startPts = ipkt->pts;
            else
                startPts = 0;
            
            if (ipkt->dts != AV_NOPTS_VALUE)
                startDts = ipkt->pts;
            else
                startDts = 0;
            
        
        } else if(!keyframeMessage){
            Warning("Waiting for keyframe before starting recording");
            keyframeMessage = true;
        }
        
        if(keyframeMessage){
            keyframeSkipNumber++;
            return -1;//FIXME bad opkt not freed
        }

    }else{
        if(keyframeMessage){
            Warning("Skipped %d frames waiting for keyframe", keyframeSkipNumber);
            keyframeMessage = false;
            
            if (ipkt->pts != AV_NOPTS_VALUE)
                startPts = ipkt->pts;
            else
                startPts = 0;
            
            if (ipkt->dts != AV_NOPTS_VALUE)
                startDts = ipkt->pts;
            else
                startDts = 0;
        }
    }*/

    
    //opkt.stream_index = video_st->index;
    
    //Scale the PTS of the outgoing packet to be the correct time base
    if (ipkt->pts != AV_NOPTS_VALUE)
        opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, video_st->time_base) - ost_tb_start_time;
    else
        opkt.pts = AV_NOPTS_VALUE;
    
    //Scale the DTS of the outgoing packet to be the correct time base
    if(ipkt->dts == AV_NOPTS_VALUE)
        opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, video_st->time_base);
    else
        opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, video_st->time_base);
    opkt.dts -= ost_tb_start_time;
    
    opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, video_st->time_base);
    opkt.flags = ipkt->flags;
    opkt.pos=-1;
    
    //TODO: Should be checking if not H264, mpeg1, etc
    //Maybe the check isn't needed if we're only going to do this for H264 video incoming
    
    opkt.data = ipkt->data;
    opkt.size = ipkt->size;
    opkt.stream_index = ipkt->stream_index;
    /*opkt.flags |= AV_PKT_FLAG_KEY;*/
    
    if (video_st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (fmt->flags & AVFMT_RAWPICTURE)) {
        /* store AVPicture in AVPacket, as expected by the output format */
        //Info("Raw picture storage");
        avpicture_fill(&pict, opkt.data, video_st->codec->pix_fmt, video_st->codec->width, video_st->codec->height);
        opkt.data = (uint8_t *)&pict;
        opkt.size = sizeof(AVPicture);
        opkt.flags |= AV_PKT_FLAG_KEY;
    }
    
    
    int ret;
    ret = av_interleaved_write_frame(oc, &opkt);
    if(ret<0){
        Fatal("Error encoding video frame packet: %s\n", av_make_error_string(szErr,1024,ret));
    }
    
    av_free_packet(&opkt);
    return 0;
    
}
Ejemplo n.º 25
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 )