Transmitting video with HackRF

I just got my HackRF and was playing with it ever since.
One of my interests is Digital Amateur TV.
I was searching for solutions to do DATV using HackRF. Finally, I was able to test transmitting video via HackRF.

I followed the following 2 sites and modified commands and dvbt-hackrf.py.
1. http://photohamrad.blogspot.com/2015/06/transmitting-video-with-hackrf-blue.html
2. https://irrational.net/2014/03/02/digital-atv/

I only tested on 441MHz. I will need to tweak on ffmpeg switches and python code to make the video smoother. Right now the video only shows the initial image and no movement. avconv may be better but I was not able to install it, so I used ffmpeg.

My next challenge is to transmit in DVB-S2 and receive the video with Satellite set-top receiver.
So far, I am not able to build dvb-s package. I also ordered Adalm Pluto from Arrow Electronics but they have not shipped it.

Environment:
Transmitter PC
Lenovo ThinkPad X201 Core i5 CPU 4GB RAM
Ubuntu Mate 18.04
HackRF One

Receiver PC
Lenovo ThinkPad X200 Core Duo 4GB RAM
Ubuntu Mate 18.04
RTL-SDR

Transmitter side:
Install gnuradio.
Install dvb-t package.
[Terminal 1]
>cd gr-dvbt
>mkfifo in.fifo
>ffmpeg -re -thread_queue_size 1000 -i /dev/video0 -vcodec mpeg2video -f alsa -i hw:0,0 -acodec mp2 -s 640x480 -r 25 -b:v 2M -minrate:v 2M -maxrate:v 2M -bufsize:v 1.4M -ac 2 -b:a 48k -mpegts_transport_stream_id 1025 -mpegts_service_id 1 -mpegts_pmt_start_pid 0x0fff -mpegts_start_pid 0x0121  -muxrate 2M -f mpegts -y in.fifo
[Terminal 2]
>dvbt-hackrf.py in.fifo

Receiver side:

>vlc dvb://frequency=441000000:bandwidth=6
 
 [dvbt-hackrf.py]
#!/usr/bin/env /usr/bin/python

# Copyright 2014 Ron Economos (w6rz@comcast.net)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .

from gnuradio import blocks
from gnuradio import digital
from gnuradio import fft
from gnuradio import gr
from gnuradio.fft import window
import dvbt
import osmosdr
import sys

def main(args):
    nargs = len(args)
    if nargs == 1:
        infile  = args[0]
        outfile = None
    elif nargs == 2:
        infile  = args[0]
        outfile  = args[1]
    else:
        sys.stderr.write("Usage: dvbt-hackrf.py input_file [output_file]\n");
        sys.exit(1)

    channel_mhz = 6
    mode = dvbt.T2k
    code_rate = dvbt.C1_2
    constellation = dvbt.QPSK
    guard_interval = dvbt.G1_32
    symbol_rate = channel_mhz * 8000000.0 / 7
    center_freq = 441000000
    txvga1_gain = -4
    txvga2_gain = 25

    if mode == dvbt.T2k:
        factor = 1
        carriers = 2048
    elif mode == dvbt.T8k:
        factor = 4
        carriers = 8192

    if guard_interval == dvbt.G1_32:
        gi = carriers / 32
    elif guard_interval == dvbt.G1_16:
        gi = carriers / 16
    elif guard_interval == dvbt.G1_8:
        gi = carriers / 8
    elif guard_interval == dvbt.G1_4:
        gi = carriers / 4

    if channel_mhz == 8:
        bandwidth = 8750000
    elif channel_mhz == 7:
        bandwidth = 7000000
    elif channel_mhz == 6:
        bandwidth = 6000000
    elif channel_mhz == 5:
        bandwidth = 5000000
    else:
        bandwidth = 8750000

    tb = gr.top_block()

    src = blocks.file_source(gr.sizeof_char, infile, True)

    dvbt_energy_dispersal = dvbt.energy_dispersal(1 * factor)
    dvbt_reed_solomon_enc = dvbt.reed_solomon_enc(2, 8, 0x11d, 255, 239, 8, 51, (8 * factor))
    dvbt_convolutional_interleaver = dvbt.convolutional_interleaver((136 * factor), 12, 17)
    dvbt_inner_coder = dvbt.inner_coder(1, (1512 * factor), constellation, dvbt.NH, code_rate)
    dvbt_bit_inner_interleaver = dvbt.bit_inner_interleaver((1512 * factor), constellation, dvbt.NH, mode)
    dvbt_symbol_inner_interleaver = dvbt.symbol_inner_interleaver((1512 * factor), mode, 1)
    dvbt_dvbt_map = dvbt.dvbt_map((1512 * factor), constellation, dvbt.NH, mode, 1)
    dvbt_reference_signals = dvbt.reference_signals(gr.sizeof_gr_complex, (1512 * factor), carriers, constellation, dvbt.NH, code_rate, code_rate, dvbt.G1_32, mode, 0, 0)
    fft_vxx = fft.fft_vcc(carriers, False, (window.rectangular(carriers)), True, 10)
    digital_ofdm_cyclic_prefixer = digital.ofdm_cyclic_prefixer(carriers, carriers+(gi), 0, "")
    blocks_multiply_const_vxx = blocks.multiply_const_vcc((0.0022097087 * 2.5, ))

    out = osmosdr.sink() #args="bladerf=0,buffers=128,buflen=32768")
    out.set_sample_rate(symbol_rate)
    out.set_center_freq(center_freq, 0)
    out.set_freq_corr(0, 0)
    out.set_gain(txvga2_gain, 0)
    out.set_bb_gain(txvga1_gain, 0)
    out.set_bandwidth(bandwidth, 0)

    tb.connect(src, dvbt_energy_dispersal)
    tb.connect(dvbt_energy_dispersal, dvbt_reed_solomon_enc)
    tb.connect(dvbt_reed_solomon_enc, dvbt_convolutional_interleaver)
    tb.connect(dvbt_convolutional_interleaver, dvbt_inner_coder)
    tb.connect(dvbt_inner_coder, dvbt_bit_inner_interleaver)
    tb.connect(dvbt_bit_inner_interleaver, dvbt_symbol_inner_interleaver)
    tb.connect(dvbt_symbol_inner_interleaver, dvbt_dvbt_map)
    tb.connect(dvbt_dvbt_map, dvbt_reference_signals)
    tb.connect(dvbt_reference_signals, fft_vxx)
    tb.connect(fft_vxx, digital_ofdm_cyclic_prefixer)
    tb.connect(digital_ofdm_cyclic_prefixer, blocks_multiply_const_vxx)
    tb.connect(blocks_multiply_const_vxx, out)


    if outfile:
        dst = blocks.file_sink(gr.sizeof_gr_complex, outfile)
        tb.connect(blocks_multiply_const_vxx, dst)

    tb.run()


if __name__ == '__main__':
    main(sys.argv[1:])
 
 
 * Disclaimer: You need to have proper license to follow the above. It is
 illegal to transmit radio waves without license. I am not responsible 
for any damages caused by following this posting. This posting is for 
informational purposes only.

Comments

Popular posts from this blog

Transmitting video with ADALM PLUTO to Satellite receiver

Python GUI app to control X6100 Armbian