
Recherche avancée
Médias (91)
-
DJ Z-trip - Victory Lap : The Obama Mix Pt. 2
15 septembre 2011
Mis à jour : Avril 2013
Langue : English
Type : Audio
-
Matmos - Action at a Distance
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
DJ Dolores - Oslodum 2004 (includes (cc) sample of “Oslodum” by Gilberto Gil)
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Danger Mouse & Jemini - What U Sittin’ On ? (starring Cee Lo and Tha Alkaholiks)
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Cornelius - Wataridori 2
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
The Rapture - Sister Saviour (Blackstrobe Remix)
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
Autres articles (41)
-
Des sites réalisés avec MediaSPIP
2 mai 2011, parCette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page. -
Use, discuss, criticize
13 avril 2011, parTalk to people directly involved in MediaSPIP’s development, or to people around you who could use MediaSPIP to share, enhance or develop their creative projects.
The bigger the community, the more MediaSPIP’s potential will be explored and the faster the software will evolve.
A discussion list is available for all exchanges between users. -
Supporting all media types
13 avril 2011, parUnlike most software and media-sharing platforms, MediaSPIP aims to manage as many different media types as possible. The following are just a few examples from an ever-expanding list of supported formats : images : png, gif, jpg, bmp and more audio : MP3, Ogg, Wav and more video : AVI, MP4, OGV, mpg, mov, wmv and more text, code and other data : OpenOffice, Microsoft Office (Word, PowerPoint, Excel), web (html, CSS), LaTeX, Google Earth and (...)
Sur d’autres sites (7319)
-
Video Recording on Android from Frames using javaCV
23 juin 2016, par jawad bin zafarI am using this library javaCV to record video on android. They have provided a sample VideoRecording Activity But There is some bug which I could not figure out what I am doing it wrong or what is missing which causing this bug.
package org.bytedeco.javacv.recordactivity;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import java.io.IOException;
import java.nio.ShortBuffer;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import static org.bytedeco.javacpp.opencv_core.*;
public class RecordActivity extends Activity implements OnClickListener {
private final static String CLASS_LABEL = "RecordActivity";
private final static String LOG_TAG = CLASS_LABEL;
private PowerManager.WakeLock mWakeLock;
private String ffmpeg_link = "/mnt/sdcard/stream.flv";
long startTime = 0;
boolean recording = false;
private volatile FFmpegFrameRecorder recorder;
private boolean isPreviewOn = false;
private int sampleAudioRateInHz = 44100;
private int imageWidth = 320;
private int imageHeight = 240;
private int frameRate = 30;
/* audio data getting thread */
private AudioRecord audioRecord;
private AudioRecordRunnable audioRecordRunnable;
private Thread audioThread;
volatile boolean runAudioThread = true;
/* video data getting thread */
private Camera cameraDevice;
private CameraView cameraView;
private IplImage yuvIplimage = null;
/* layout setting */
private final int bg_screen_bx = 232;
private final int bg_screen_by = 128;
private final int bg_screen_width = 700;
private final int bg_screen_height = 500;
private final int bg_width = 1123;
private final int bg_height = 715;
private final int live_width = 640;
private final int live_height = 480;
private int screenWidth, screenHeight;
private Button btnRecorderControl;
/** The number of seconds in the continuous record loop (or 0 to disable loop). */
final int RECORD_LENGTH = 10;
IplImage[] images;
long[] timestamps;
ShortBuffer[] samples;
int imagesIndex, samplesIndex;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, CLASS_LABEL);
mWakeLock.acquire();
initLayout();
}
@Override
protected void onResume() {
super.onResume();
if (mWakeLock == null) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, CLASS_LABEL);
mWakeLock.acquire();
}
}
@Override
protected void onPause() {
super.onPause();
if (mWakeLock != null) {
mWakeLock.release();
mWakeLock = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
recording = false;
if (cameraView != null) {
cameraView.stopPreview();
}
if(cameraDevice != null) {
cameraDevice.stopPreview();
cameraDevice.release();
cameraDevice = null;
}
if (mWakeLock != null) {
mWakeLock.release();
mWakeLock = null;
}
}
private void initLayout() {
/* get size of screen */
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
RelativeLayout.LayoutParams layoutParam = null;
LayoutInflater myInflate = null;
myInflate = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout topLayout = new RelativeLayout(this);
setContentView(topLayout);
LinearLayout preViewLayout = (LinearLayout) myInflate.inflate(R.layout.main, null);
layoutParam = new RelativeLayout.LayoutParams(screenWidth, screenHeight);
topLayout.addView(preViewLayout, layoutParam);
/* add control button: start and stop */
btnRecorderControl = (Button) findViewById(R.id.recorder_control);
btnRecorderControl.setText("Start");
btnRecorderControl.setOnClickListener(this);
/* add camera view */
int display_width_d = (int) (1.0 * bg_screen_width * screenWidth / bg_width);
int display_height_d = (int) (1.0 * bg_screen_height * screenHeight / bg_height);
int prev_rw, prev_rh;
if (1.0 * display_width_d / display_height_d > 1.0 * live_width / live_height) {
prev_rh = display_height_d;
prev_rw = (int) (1.0 * display_height_d * live_width / live_height);
} else {
prev_rw = display_width_d;
prev_rh = (int) (1.0 * display_width_d * live_height / live_width);
}
layoutParam = new RelativeLayout.LayoutParams(prev_rw, prev_rh);
layoutParam.topMargin = (int) (1.0 * bg_screen_by * screenHeight / bg_height);
layoutParam.leftMargin = (int) (1.0 * bg_screen_bx * screenWidth / bg_width);
cameraDevice = Camera.open();
Log.i(LOG_TAG, "cameara open");
cameraView = new CameraView(this, cameraDevice);
topLayout.addView(cameraView, layoutParam);
Log.i(LOG_TAG, "cameara preview start: OK");
}
//---------------------------------------
// initialize ffmpeg_recorder
//---------------------------------------
private void initRecorder() {
Log.w(LOG_TAG,"init recorder");
if (RECORD_LENGTH > 0) {
imagesIndex = 0;
images = new IplImage[RECORD_LENGTH * frameRate];
timestamps = new long[images.length];
for (int i = 0; i < images.length; i++) {
images[i] = IplImage.create(imageWidth, imageHeight, IPL_DEPTH_8U, 2);
timestamps[i] = -1;
}
} else if (yuvIplimage == null) {
yuvIplimage = IplImage.create(imageWidth, imageHeight, IPL_DEPTH_8U, 2);
Log.i(LOG_TAG, "create yuvIplimage");
}
Log.i(LOG_TAG, "ffmpeg_url: " + ffmpeg_link);
recorder = new FFmpegFrameRecorder(ffmpeg_link, imageWidth, imageHeight, 1);
recorder.setFormat("flv");
recorder.setSampleRate(sampleAudioRateInHz);
// Set in the surface changed method
recorder.setFrameRate(frameRate);
Log.i(LOG_TAG, "recorder initialize success");
audioRecordRunnable = new AudioRecordRunnable();
audioThread = new Thread(audioRecordRunnable);
runAudioThread = true;
}
public void startRecording() {
initRecorder();
try {
recorder.start();
startTime = System.currentTimeMillis();
recording = true;
audioThread.start();
} catch (FFmpegFrameRecorder.Exception e) {
e.printStackTrace();
}
}
public void stopRecording() {
runAudioThread = false;
try {
audioThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
audioRecordRunnable = null;
audioThread = null;
if (recorder != null && recording) {
if (RECORD_LENGTH > 0) {
Log.v(LOG_TAG,"Writing frames");
try {
int firstIndex = imagesIndex % samples.length;
int lastIndex = (imagesIndex - 1) % images.length;
if (imagesIndex <= images.length) {
firstIndex = 0;
lastIndex = imagesIndex - 1;
}
if ((startTime = timestamps[lastIndex] - RECORD_LENGTH * 1000000L) < 0) {
startTime = 0;
}
if (lastIndex < firstIndex) {
lastIndex += images.length;
}
for (int i = firstIndex; i <= lastIndex; i++) {
long t = timestamps[i % timestamps.length] - startTime;
if (t >= 0) {
if (t > recorder.getTimestamp()) {
recorder.setTimestamp(t);
}
recorder.record(images[i % images.length]);
}
}
firstIndex = samplesIndex % samples.length;
lastIndex = (samplesIndex - 1) % samples.length;
if (samplesIndex <= samples.length) {
firstIndex = 0;
lastIndex = samplesIndex - 1;
}
if (lastIndex < firstIndex) {
lastIndex += samples.length;
}
for (int i = firstIndex; i <= lastIndex; i++) {
recorder.record(samples[i % samples.length]);
}
} catch (FFmpegFrameRecorder.Exception e) {
Log.v(LOG_TAG,e.getMessage());
e.printStackTrace();
}
}
recording = false;
Log.v(LOG_TAG,"Finishing recording, calling stop and release on recorder");
try {
recorder.stop();
recorder.release();
} catch (FFmpegFrameRecorder.Exception e) {
e.printStackTrace();
}
recorder = null;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (recording) {
stopRecording();
}
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
//---------------------------------------------
// audio thread, gets and encodes audio data
//---------------------------------------------
class AudioRecordRunnable implements Runnable {
@Override
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
// Audio
int bufferSize;
ShortBuffer audioData;
int bufferReadResult;
bufferSize = AudioRecord.getMinBufferSize(sampleAudioRateInHz,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleAudioRateInHz,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
if (RECORD_LENGTH > 0) {
samplesIndex = 0;
samples = new ShortBuffer[RECORD_LENGTH * sampleAudioRateInHz * 2 / bufferSize + 1];
for (int i = 0; i < samples.length; i++) {
samples[i] = ShortBuffer.allocate(bufferSize);
}
} else {
audioData = ShortBuffer.allocate(bufferSize);
}
Log.d(LOG_TAG, "audioRecord.startRecording()");
audioRecord.startRecording();
/* ffmpeg_audio encoding loop */
while (runAudioThread) {
if (RECORD_LENGTH > 0) {
audioData = samples[samplesIndex++ % samples.length];
audioData.position(0).limit(0);
}
//Log.v(LOG_TAG,"recording? " + recording);
bufferReadResult = audioRecord.read(audioData.array(), 0, audioData.capacity());
audioData.limit(bufferReadResult);
if (bufferReadResult > 0) {
Log.v(LOG_TAG,"bufferReadResult: " + bufferReadResult);
// If "recording" isn't true when start this thread, it never get's set according to this if statement...!!!
// Why? Good question...
if (recording) {
if (RECORD_LENGTH <= 0) try {
recorder.record(audioData);
//Log.v(LOG_TAG,"recording " + 1024*i + " to " + 1024*i+1024);
} catch (FFmpegFrameRecorder.Exception e) {
Log.v(LOG_TAG,e.getMessage());
e.printStackTrace();
}
}
}
}
Log.v(LOG_TAG,"AudioThread Finished, release audioRecord");
/* encoding finish, release recorder */
if (audioRecord != null) {
audioRecord.stop();
audioRecord.release();
audioRecord = null;
Log.v(LOG_TAG,"audioRecord released");
}
}
}
//---------------------------------------------
// camera thread, gets and encodes video data
//---------------------------------------------
class CameraView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera) {
super(context);
Log.w("camera","camera view");
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(CameraView.this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCamera.setPreviewCallback(CameraView.this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
stopPreview();
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.v(LOG_TAG,"Setting imageWidth: " + imageWidth + " imageHeight: " + imageHeight + " frameRate: " + frameRate);
Camera.Parameters camParams = mCamera.getParameters();
camParams.setPreviewSize(imageWidth, imageHeight);
Log.v(LOG_TAG,"Preview Framerate: " + camParams.getPreviewFrameRate());
camParams.setPreviewFrameRate(frameRate);
mCamera.setParameters(camParams);
startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
mHolder.addCallback(null);
mCamera.setPreviewCallback(null);
} catch (RuntimeException e) {
// The camera has probably just been released, ignore.
}
}
public void startPreview() {
if (!isPreviewOn && mCamera != null) {
isPreviewOn = true;
mCamera.startPreview();
}
}
public void stopPreview() {
if (isPreviewOn && mCamera != null) {
isPreviewOn = false;
mCamera.stopPreview();
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (audioRecord == null || audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
startTime = System.currentTimeMillis();
return;
}
if (RECORD_LENGTH > 0) {
int i = imagesIndex++ % images.length;
yuvIplimage = images[i];
timestamps[i] = 1000 * (System.currentTimeMillis() - startTime);
}
/* get video data */
if (yuvIplimage != null && recording) {
yuvIplimage.getByteBuffer().put(data);
if (RECORD_LENGTH <= 0) try {
Log.v(LOG_TAG,"Writing Frame");
long t = 1000 * (System.currentTimeMillis() - startTime);
if (t > recorder.getTimestamp()) {
recorder.setTimestamp(t);
}
recorder.record(yuvIplimage);
} catch (FFmpegFrameRecorder.Exception e) {
Log.v(LOG_TAG,e.getMessage());
e.printStackTrace();
}
}
}
}
@Override
public void onClick(View v) {
if (!recording) {
startRecording();
Log.w(LOG_TAG, "Start Button Pushed");
btnRecorderControl.setText("Stop");
} else {
// This will trigger the audio recording loop to stop and then set isRecorderStart = false;
stopRecording();
Log.w(LOG_TAG, "Stop Button Pushed");
btnRecorderControl.setText("Start");
}
}
}I am getting this error
The type org.bytedeco.javacpp.avutil$AVFrame cannot be resolved. It is indirectly referenced from required .class files
at following line in the above code
if (RECORD_LENGTH <= 0) try {
recorder.record(audioData);
//Log.v(LOG_TAG,"recording " + 1024*i + " to " + 1024*i+1024);
}at recorder.record(audioData). I don’t know what I am doing wrong here. New to JavaCV. Any help will be appreciated.
-
using libav instead of ffmpeg
21 janvier 2015, par n00bieI want to streaming video over http, i am using ogg(theora + vorbis), now i have sender and receiver, and i can run them using command line :
Sender :
ffmpeg -f video4linux2 -s 320x240 -i /dev/mycam -codec:v libtheora -qscale:v 5 -f ogg http://127.0.0.1:8080
Receiver :
sudo gst-launch-0.10 tcpserversrc port = 8080 ! oggdemux ! theoradec ! autovideosink
Now, sender sends both audio and video, but receiver plays only video.
It works perfect, but now i want not to use ffmpeg and use only libav* instead.
Here’s my class for streaming :
class VCORE_LIBRARY_EXPORT VVideoWriter : private boost::noncopyable
{
public:
VVideoWriter( );
~VVideoWriter( );
bool openFile( const std::string& name,
int fps, int videoBitrate, int width, int height,
int audioSampleRate, bool stereo, int audioBitrate );
void close( );
bool writeVideoFrame( const uint8_t* image, int64_t timestamp );
bool writeAudioFrame( const int16_t* data, int64_t timestamp );
int audioFrameSize( ) const;
private:
AVFrame *m_videoFrame;
AVFrame *m_audioFrame;
AVFormatContext *m_context;
AVStream *m_videoStream;
AVStream *m_audioStream;
int64_t m_startTime;
};Initialization :
bool VVideoWriter::openFile( const std::string& name,
int fps, int videoBitrate, int width, int height,
int audioSampleRate, bool stereo, int audioBitrate )
{
if( ! m_context )
{
// initalize the AV context
m_context = avformat_alloc_context( );
assert( m_context );
// get the output format
m_context->oformat = av_guess_format( "ogg", name.c_str( ), nullptr );
if( m_context->oformat )
{
strcpy( m_context->filename, name.c_str( ) );
auto codecID = AV_CODEC_ID_THEORA;
auto codec = avcodec_find_encoder( codecID );
if( codec )
{
m_videoStream = avformat_new_stream( m_context, codec );
assert( m_videoStream );
// initalize codec
auto codecContext = m_videoStream->codec;
bool globalHeader = m_context->oformat->flags & AVFMT_GLOBALHEADER;
if( globalHeader )
codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
codecContext->codec_id = codecID;
codecContext->codec_type = AVMEDIA_TYPE_VIDEO;
codecContext->width = width;
codecContext->height = height;
codecContext->time_base.den = fps;
codecContext->time_base.num = 1;
codecContext->bit_rate = videoBitrate;
codecContext->pix_fmt = PIX_FMT_YUV420P;
codecContext->flags |= CODEC_FLAG_QSCALE;
codecContext->global_quality = FF_QP2LAMBDA * 5;
int res = avcodec_open2( codecContext, codec, nullptr );
if( res >= 0 )
{
auto codecID = AV_CODEC_ID_VORBIS;
auto codec = avcodec_find_encoder( codecID );
if( codec )
{
m_audioStream = avformat_new_stream( m_context, codec );
assert( m_audioStream );
// initalize codec
auto codecContext = m_audioStream->codec;
bool globalHeader = m_context->oformat->flags & AVFMT_GLOBALHEADER;
if( globalHeader )
codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
codecContext->codec_id = codecID;
codecContext->codec_type = AVMEDIA_TYPE_AUDIO;
codecContext->sample_fmt = AV_SAMPLE_FMT_FLTP;
codecContext->bit_rate = audioBitrate;
codecContext->sample_rate = audioSampleRate;
codecContext->channels = stereo ? 2 : 1;
codecContext->channel_layout = stereo ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
res = avcodec_open2( codecContext, codec, nullptr );
if( res >= 0 )
{
// try to open the file
if( avio_open( &m_context->pb, m_context->filename, AVIO_FLAG_WRITE ) >= 0 )
{
m_audioFrame->nb_samples = codecContext->frame_size;
m_audioFrame->format = codecContext->sample_fmt;
m_audioFrame->channel_layout = codecContext->channel_layout;
boost::posix_time::ptime time_t_epoch( boost::gregorian::date( 1970, 1, 1 ) );
m_context->start_time_realtime = ( boost::posix_time::microsec_clock::universal_time( ) - time_t_epoch ).total_microseconds( );
m_startTime = -1;
// write the header
if( avformat_write_header( m_context, nullptr ) >= 0 )
{
return true;
}
else std::cerr << "VVideoWriter: failed to write video header" << std::endl;
}
else std::cerr << "VVideoWriter: failed to open video file " << name << std::endl;
}
else std::cerr << "VVideoWriter: failed to initialize audio codec" << std::endl;
}
else std::cerr << "VVideoWriter: requested audio codec is not supported" << std::endl;
}
else std::cerr << "VVideoWriter: failed to initialize video codec" << std::endl;
}
else std::cerr << "VVideoWriter: requested video codec is not supported" << std::endl;
}
else std::cerr << "VVideoWriter: requested video format is not supported" << std::endl;
avformat_free_context( m_context );
m_context = nullptr;
m_videoStream = nullptr;
m_audioStream = nullptr;
}
return false;
}Writing video :
bool VVideoWriter::writeVideoFrame( const uint8_t* image, int64_t timestamp )
{
if( m_context ) {
auto codecContext = m_videoStream->codec;
avpicture_fill( reinterpret_cast( m_videoFrame ),
const_cast( image ),
codecContext->pix_fmt, codecContext->width, codecContext->height );
AVPacket pkt;
av_init_packet( & pkt );
pkt.data = nullptr;
pkt.size = 0;
int gotPacket = 0;
if( ! avcodec_encode_video2( codecContext, &pkt, m_videoFrame, & gotPacket ) ) {
if( gotPacket == 1 ) {
pkt.stream_index = m_videoStream->index;
int res;
{
pkt.pts = AV_NOPTS_VALUE;
pkt.dts = AV_NOPTS_VALUE;
pkt.stream_index = m_videoStream->index;
res = av_write_frame( m_context, &pkt );
}
av_free_packet( & pkt );
return res >= 0;
}
assert( ! pkt.size );
return true;
}
}
return false;
}Writing audio (now i write test dummy audio) :
bool VVideoWriter::writeAudioFrame( const int16_t* data, int64_t timestamp )
{
if( m_context ) {
auto codecContext = m_audioStream->codec;
int buffer_size = av_samples_get_buffer_size(nullptr, codecContext->channels, codecContext->frame_size, codecContext->sample_fmt, 0);
float *samples = (float*)av_malloc(buffer_size);
for (int i = 0; i < buffer_size / sizeof(float); i++)
samples[i] = 1000. * sin((double)i/2.);
int ret = avcodec_fill_audio_frame( m_audioFrame, codecContext->channels, codecContext->sample_fmt, (const uint8_t*)samples, buffer_size, 0);
assert( ret >= 0 );
(void)(ret);
AVPacket pkt;
av_init_packet( & pkt );
pkt.data = nullptr;
pkt.size = 0;
int gotPacket = 0;
if( ! avcodec_encode_audio2( codecContext, &pkt, m_audioFrame, & gotPacket ) ) {
if( gotPacket == 1 ) {
pkt.stream_index = m_audioStream->index;
int res;
{
pkt.pts = AV_NOPTS_VALUE;
pkt.dts = AV_NOPTS_VALUE;
pkt.stream_index = m_audioStream->index;
res = av_write_frame( m_context, &pkt );
}
av_free_packet( & pkt );
return res >= 0;
}
assert( ! pkt.size );
return true;
}
return false;
}
return false;
}Here’s test example (i send video from webcam and dummy audio) :
class TestVVideoWriter : public sigslot::has_slots<>
{
public:
TestVVideoWriter( ) :
m_fileOpened( false )
{
}
void onCapturedFrame( cricket::VideoCapturer*, const cricket::CapturedFrame* capturedFrame )
{
if( m_fileOpened ) {
m_writer.writeVideoFrame( reinterpret_cast<const>( capturedFrame->data ),
capturedFrame->time_stamp / 1000 );
m_writer.writeAudioFrame( nullptr , 0 );
} else {
m_fileOpened = m_writer.openFile( "http://127.0.0.1:8080",
15, 40000, capturedFrame->width, capturedFrame->height,
16000, false, 64000 );
}
}
public:
vcore::VVideoWriter m_writer;
bool m_fileOpened;
};
TestVVideoWriter testWriter;
BOOST_AUTO_TEST_SUITE(TEST_VIDEO_WRITER)
BOOST_AUTO_TEST_CASE(testWritingVideo)
{
cricket::LinuxDeviceManager deviceManager;
std::vector devs;
if( deviceManager.GetVideoCaptureDevices( &devs ) ) {
if( devs.size( ) ) {
boost::shared_ptr camera( deviceManager.CreateVideoCapturer( devs[ 0 ] ) );
if( camera ) {
cricket::VideoFormat format( 320, 240, cricket::VideoFormat::FpsToInterval( 30 ),
camera->GetSupportedFormats( )->front( ).fourcc );
cricket::VideoFormat best;
if( camera->GetBestCaptureFormat( format, &best ) ) {
camera->SignalFrameCaptured.connect( &testWriter, &TestVVideoWriter::onCapturedFrame );
if( camera->Start( best ) != cricket::CS_FAILED ) {
boost::this_thread::sleep( boost::posix_time::seconds( 10 ) );
return;
}
}
}
}
}
std::cerr << "Problem has occured with camera" << std::endl;
}
BOOST_AUTO_TEST_SUITE_END() // TEST_VIDEO_WRITER
</const>But, in this case, gstreamer start playing video only when my test program stop executing (after 10 seconds in this case). It does not suit me, i want gstreamer start playing immediately after starting my test program.
Could someone help me ?
P.S. Sorry for my English.
-
Dreamcast SD Adapter and DreamShell
31 décembre 2014, par Multimedia Mike — Sega DreamcastNope ! I’m never going to let go of the Sega Dreamcast hacking. When I was playing around with Dreamcast hacking early last year, I became aware that there is such a thing as an SD card adapter for the DC that plugs into the port normally reserved for the odd DC link cable. Of course I wanted to see what I could do with it.
The primary software that leverages the DC SD adapter is called DreamShell. Working with this adapter and the software requires some skill and guesswork. Searching for these topics tends to turn up results from various forums where people are trying to cargo-cult their way to solutions. I have a strange feeling that this post might become the unofficial English-language documentation on the matter.
Use Cases
What can you do with this thing ? Undoubtedly, the primary use is for backing up (ripping) the contents of GD-ROMs (the custom optical format used for the DC) and playing those backed up (ripped) copies. Presumably, users of this device leverage the latter use case more than the former, i.e., download ripped games, load them on the SD card, and launch them using DreamShell.However, there are other uses such as multimedia playback, system exploration, BIOS reprogramming, high-level programming, and probably a few other things I haven’t figured out yet.
Delivery
I put in an order via the dc-sd.com website and in about 2 short months, the item arrived from China. This marked my third lifetime delivery from China and curiously, all 3 of the shipments have pertained to the Sega Dreamcast.
I thought it was very interesting that this adapter came in such complete packaging. The text is all in Chinese, though the back states “Windows 98 / ME / 2000 / XP, Mac OS 9.1, LINUX2.4”. That’s what tipped me off that they must have just cannibalized some old USB SD card readers and packaging in order to create these. Closer inspection of the internals through the translucent pink case confirms this.
Usage
According to its change log, DreamShell has been around for a long time with version 1.0.0 released in February of 2004. The current version is 4.0.0 RC3. There are several downloads available :- DreamShell 4.0 RC 3 CDI Image
- DreamShell 4.0 RC 3 + Boot Loader
- DreamShell 4.0 RC 3 + Core CDI image
Option #2 worked for me. It contains a CDI disc image and the DreamShell files in a directory named DS/.
Burn the CDI to a CD-R in the normal way you would burn a bootable Dreamcast disc from a CDI image. This is open-ended and left as an exercise to the reader, since there are many procedures depending on platform. On Linux, I used a small script I found once called burncdi-dc.sh.
Then, copy the contents of the DS/ folder to an SD card. As for filesystem, FAT16 and FAT32 are both known to work. The files in DS/ should land in the root of the SD card ; the folder DS/ should not be in the root.
Plug the SD card into the DC SD adapter and plug the adapter in the link cable port on the back of the Dreamcast. Then, boot the disc. If it works, you will see this minor corruption of the usual Sega licensing screen :
Then, there will be a brief white-on-black text screen that explains the booting process :
Then, there will be the main DreamShell logo :
Finally, you will land on the DreamShell main desktop :
Skepticism
At first, I was supremely skeptical of the idea that this SD adapter could perform speedily enough to play games reasonably. This was predicated on the observation that my DC coder’s cable that I used to use for homebrew development could not transfer faster than 115200 bits/second, amounting to about 11 kbytes/sec. I assumed that this was a fundamental limitation of the link port.In fact, I ripped a few of my Dreamcast discs over a decade ago and still have those rips lying around. So I copied the ISO image of Resident Evil : Code Veronica — the game I personally played most on the DC — to the SD card (anywhere works) and used the “ISO loader” icon seen on the desktop above to launch the game.
It works :
The opening FMV plays at full speed. Everything loads as fast as I remember. I was quite surprised.
Digression : My assumptions about serial speeds have often been mistaken. 10 years ago, I heard stories about how we would soon be able to watch streaming video on our cell phones. I scoffed because I thought the 56K limitation of dialup modems was some sort of fundamental speed-of-light type of limitation for telephony bandwidth, wired or wireless.
The desktop menu also includes a ‘speedtest’ tool that profiles the write and read performance of your preferred storage medium. For my fastest SD card (a PNY 2 GB card) :
This is probably more representative of the true adapter bandwidth as reading and writing is a good deal faster through more modern interfaces on PC and Mac with this same card.
Look at the other options on the speedtest console. Hard drive ? Apparently, it’s possible, but it requires a good deal more hardware hacking than just purchasing this SD adapter.
Ripping
As you can see from the Resident Evil screenshot, playing games works quite nicely. How about ripping ? I’m pleased to say that DreamShell has a beautiful ripping interface :
Enter a name for the disc (or read the disc label), select the storage medium, and let it, well, rip. It indicates which track it’s working on and the Sega logo acts as a progress bar, shading blue as the track rip progresses.
I’m finally, efficiently, archiving that collection of Sega Dreamcast demo discs ; I’m hoping they’ll eventually find a home at the Internet Archive. How is overall ripping performance ? Usually about 38-40 minutes to rip a full 900-1000 MB. That certainly beats the 27-28 hours that were required when I performed the ripping at 11 kbytes/sec via the DC coders cable.
All is well until I get a sector reading error :
That’s when it can come in handy to have 3 DC consoles (see ?! not crazy !).
Other Uses
There’s a file explorer. You can browse the filesystem of the SD card, visual memory unit, or the CD portion of the GD-ROM (would be more useful if it accessed the GD area). There are FFmpeg files included. So I threw a random Cinepak file and random MPEG-1 file at it to see what happens. MPEG-1 didn’t do anything, but this Cinepak file from some Sierra game played handily :
If you must enter strings, it helps to have a Dreamcast keyboard (which I do). Failing that, here’s a glimpse of the onscreen keyboard that DreamShell equips :
Learning to use it is a game in itself.
There is an option of installing DreamShell in the BIOS. I did not attempt this. I don’t know if it’s possible (not like there’s a lot of documentation)– perhaps a custom BIOS modchip is needed. But here’s what the screen looks like :
There is also a plain console to interact with (better have a physical keyboard). There are numerous file manipulation commands and custom system interaction commands. I see one interesting command called ‘addr’ that looks useful for dumping memory regions to a file.
A Lua language interpreter is also built in. I would love to play with this if I could ascertain whether DreamShell provided Dreamcast-specific APIs.
Tips And Troubleshooting
I have 3 Dreamcast consoles, affectionately named Terran, Protoss, and Zerg after the StarCraft II stickers with which they are adorned. Some seem to work better than others. Protoss seemed to be able to boot the DreamShell disc more reliably than the others. However, I was alarmed when it couldn’t boot one morning when it was churning the previous day.I think the problem is that it was just cold. That seemed to be the issue. I put in a normal GD-ROM and let it warm up on that disc for awhile and then DreamShell booted fine. So that’s my piece of cargo-culting troubleshooting advice.